2016-12-13 131 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";