开发者

C# class indexer setting dictionary not property

I am trying to implement a string indexer for a C# class, but when you set a property the dictionary gets set and not the property. It is probably something simple that i am missing, i just can't see it.

objFiveProp temp = new objFiveProp();
temp["index1"] = 3;

sets the temp._items["index1"].value to 3.

Class:

public class objFiveProp
{

    #region Properties
    private Dictionary<string, int> _items;
    public int this[string key]
    {
        get { return _items[key]; }
        set { _items[key] = value; }
    }

    public int index1 { get; set; }
    public int index2 { get; set; }
    public int index3 { get; set; }
    public int index4 { get; set; }
    public int index5 { get; set; }

    #endregion
    #region Constructor

    public objFiveProp()
    {
        index1 = 0;
        index2 = 0;
        index3 = 0;
        index4 = 0;
        index5 开发者_运维知识库= 0;
        _items = new Dictionary<string, int>();
        _items.Add("index1", index1);
        _items.Add("index2", index2);
        _items.Add("index3", index3);
        _items.Add("index4", index4);
        _items.Add("index5", index5);

    }

    #endregion

}


That's how it works. The Dictionary contains a copy of the integers you use to set it up - not a reference to the properties.

I would tackle this by using something like:

public class objFiveProp
{
    private Dictionary<string, int> _items;
    public int this[string key]
    {
        get { return _items[key]; }
        set { _items[key] = value; }
    }

    public int Index1 
    {
        get { return this["index1"]; } 
        set { this["index1"] = value; }
    }
    public int Index2
    {
        get { return this["index2"]; } 
        set { this["index2"] = value; }
    }

    // ....

    public objFiveProp()
    {
        _items = new Dictionary<string, int>();
        _items.Add("index1", index1);
        _items.Add("index2", index2);
        _items.Add("index3", index3);
        _items.Add("index4", index4);
        _items.Add("index5", index5);    
    }

#endregion

This causes your properties to always pull the values stored in your dictionary, as well as save there, so there aren't two copies of the values.


This is because in index set method you are setting the value of dictionary item

public int this[string key]
    {
        get { return _items[key]; } 
        set { _items[key] = value; } //here you are setting the value of dictionary item not the property
    }

Either, create separate property for index1, index2 and so on or in set method above add checks, a dirty solution though, to set the value of member variable depending on the value of key; Something like:

set {  
   _items[key] = value; 
   if(key == "index1")
         index1 = value;
}


int is a value type, not a reference type. When you set a value in the _items, it won't set the property, even though you initially added it from the property.

From MSDN

Variables that are based on value types directly contain values. Assigning one value type variable to another copies the contained value. This differs from the assignment of reference type variables, which copies a reference to the object but not the object itself.

If you really need to be able to access your data both from the indexer and the property, one of the simplest way would be to rewrite your properties thusly:

public int indexN
{
    get { return _items["indexN"]; }
    set { _items["indexN"] = value; }
}

Another way would be to use reflection in the indexer's setter:

public int this[string key]
{
    get { return _items[key]; }
    set 
    { 
        _items[key] = value; 
        PropertyInfo prop = this.GetType().GetProperty(key);
        if (prop != null)
        {
            prop.SetValue(this, null);
        }
    }
}

Remember though, reflection is relatively very S-L-O-W.

There are other ways to accomplish what you're trying to do as well, but perhaps the best solution is to not do this at all. Pick the best interface to your class, whether that be the indexer or the properties, and stick with it. Your code will be more maintainable (you won't have to upkeep two public interfaces to your class's data) and more readable (other coders won't need to know that the indexer and the properties are the same thing). Cheers!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜