2016-12-13 82 views
0

是否有任何可能的方法使一个索引器使用非全局索引器的整个类?这是我想要做的事情的要点。请注意,在这个例子中,你应该假装我不能移动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]; 
     } 
    } 
} 

我会再能引用名为foo15bar12data的一个项目,像这样

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

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

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

为什么你想要这第一个地方?您如何预期其行为与普通索引器不同? – EJoshuaS

+0

@EJoshuaS,我不想公开'data'的所有属性,但我也不想定义'FooX',其中X是一个数字15次。这会导致一次又一次的相同的代码,并且很难迭代'FooX'属性。我想让它更容易,所以'MyClass'的用户可以引用'Foo [15]'。 –

+0

@EJoshuaS,我怀疑我最终不得不使'Foo'成为一个函数(例如'public object Foo(int index){return data [String.Format(“foo {0}”,index)];}' ,但我真的更喜欢使用属性 –

回答

0

你需要创建一个新的类型,有Foo回报类型的实例,给其他类型的索引,并且具有索引做任何你想做的事情。

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";