自定义命名属性索引器

时间:2016-12-13 18:32:15

标签: c# c#-4.0 indexing properties

是否有任何可能的方法来创建一个使用除全局类之外的索引器的属性?这是我想要做的事情的要点。请注意,在此示例中,您应假装我无法移动data或创建另一个Dictionary

class MyClass
{
    protected Dictionary<string,object> data = new Dictionary<string,object>();
    public object Foo[int index]
    {
        get {
            string name = String.Format("foo{0}",index);
            return data[name];
        }
    }
    public object Bar[int index]
    {
        get {
            string name = String.Format("bar{0}",index);
            return data[name];
        }
    }
}

然后,我就可以像datafoo15一样引用bar12的项目

MyClass myClass = new MyClass();
Console.WriteLine(myClass.Foo[15]);
Console.WriteLine(myClass.Bar[12]);

我知道你可以做到这一点,但这不是我想要的。

    public object this[string index]
    {
        get {
            return data[index];
        }
    }

2 个答案:

答案 0 :(得分:0)

您需要创建一个新类型,让Foo返回该类型的实例,为其他类型提供索引器,并让该索引器执行您希望它执行的任何操作。

答案 1 :(得分:0)

你可以做到,但它需要跳过一些箍。 C#本身不支持索引属性。我学会了如何使用这篇文章:Easy creation of properties that support indexing in C#

首先声明一个IndexedProperty类:

public class IndexedProperty<TIndex, TValue>
{
    Action<TIndex, TValue> setAction;
    Func<TIndex, TValue> getFunc;

    public IndexedProperty(Func<TIndex, TValue> getFunc, Action<TIndex, TValue> setAction)
    {
        this.getFunc = getFunc;
        this.setAction = setAction;
    }

    public TValue this[TIndex i]
    {
        get
        {
            return getFunc(i);
        }
        set
        {
            setAction(i, value);
        }
    }
}

以下是使用它的一个例子(引用的帖子包含一个更简单的例子):

    protected Dictionary<DialogResult, string> ButtonNames { get; set; }
    public IndexedProperty<DialogResult, string> ButtonName
    {
        get
        {
            return new IndexedProperty<DialogResult, string>(
                r =>
                {
                    if (ButtonNames.ContainsKey(r)) return ButtonNames[r];
                    return r.ToString();
                }, 
                (r, val) => ButtonNames[r] = val);
        }
    }

...后来

tableLayoutPanel2.Controls.Add(new Button 
    {
        Text = ButtonName[btn], DialogResult = btn, 
        Anchor = AnchorStyles.Right
    });

ButtonNames可以从类外部设置,如:

msgbox.ButtonName[DialogResult.Cancel] = "Don't Do The Thing";