2010-07-20 71 views
4

假設我有一個數組或任何其他集合類物質和返回它像以下屬性:命名爲indexer屬性可能嗎?

public class Foo 
{ 
    public IList<Bar> Bars{get;set;} 
} 

現在,我可以寫這樣的事:

public Bar Bar[int index] 
{ 
    get 
    { 
     //usual null and length check on Bars omitted for calarity 
     return Bars[index]; 
    } 
} 
+1

的'酒吧'屬性已經支持指數,讓我有點困惑,你試圖完成什麼。 – 2010-07-20 19:18:31

+0

sure @Anthony'Foo f = new Foo(); f.Bars [0];'哇,我想我現在應該睡覺了! – TheVillageIdiot 2010-07-20 19:20:00

+0

@AnthonyPegram你可能不想公開'Bars'。它可能是一個不應該成爲'Foo'公共API的一部分的實現細節。而且,這暴露的不止是Bars的索引屬性。 'Bars'可能是高度有狀態的,暴露它可能會導致用戶違反'Foo'承諾的不變量。 – Undreren 2017-08-31 07:03:48

回答

2

根據你真正在尋找什麼,它可能已經爲你完成了。如果你想使用在酒吧集合的索引,它已經做了你::

Foo myFoo = new Foo(); 
Bar myBar = myFood.Bars[1]; 

或者,如果你正在試圖獲得以下功能:

Foo myFoo = new Foo(); 
Bar myBar = myFoo[1]; 

然後:

public Bar this[int index] 
{ 
    get { return Bars[index]; } 
} 
+1

我認爲'這'不是名爲財產。 – wishmaster35 2017-06-30 20:45:39

+0

@ wishmaster35不是。我不知道爲什麼這個答案被接受,因爲它是一個設計的味道:它強烈夫婦Foo'的'消費者'Bars'。在某些情況下,這可能並不重要,但現在'Foo'擁有自己的私人數據無法控制;每個人都可以直接在'Foo'周圍修改'Bars'。 – Undreren 2017-08-31 07:32:56

7

否 - 您不能在C#中編寫命名索引器。從C#4開始,您可以將它們用於COM對象,但不能編寫它們。

正如你已經注意到了,但是,foo.Bars[index]會做你想要什麼呢?這個答案是主要是爲未來的讀者着想。

要闡述:揭露某些類型且具有一個索引的Bars財產達到你想要什麼,但你應該考慮如何將其暴露:

  • 你想呼叫者能夠與更換集合一個不同的集合? (如果沒有,請將其設爲只讀屬性。)
  • 您是否希望呼叫者能夠修改集合?如果是這樣,怎麼樣?只需更換物品,或添加/刪除它們?你需要對此進行任何控制嗎?這些問題的答案將決定您想要公開的類型 - 可能是隻讀集合,還是具有額外驗證的自定義集合。
+0

難道你不能複製在這裏使用的相同的樣式http://msdn.microsoft.com/en-us/library/146h6tk5.aspx和取決於你如何實現該方法獲得相同的結果? – Gage 2010-07-27 17:53:03

+0

@Gage:我不確定你在說什麼...這並沒有創建一個指定的索引器,據我所知... – 2010-07-27 18:41:48

+0

@JonSkeet使用'foo.Bars [index]',因爲你在這裏建議,將'Bars'暴露給'Foo'的消費者。這意味着'Foo'實際上不能控制任何與Bars有關的不變量。此外,'Foo'的所有消費者現在都強烈地耦合到'Bars'。在這種情況下,'GetBar'和'SetBar'方法會更好,至少在信息隱藏方面。 – Undreren 2017-08-31 07:30:39

0
public class NamedIndexProp 
{ 
    private MainClass _Owner; 
    public NamedIndexProp(MainClass Owner) { _Owner = Owner; 
    public DataType this[IndexType ndx] 
    { 
     get { return _Owner.Getter(ndx); } 
     set { _Owner.Setter(ndx, value); } 
    } 
} 
public MainClass 
{ 
    private NamedIndexProp _PropName; 
    public MainClass() 
    { 
     _PropName = new NamedIndexProp(this); 
    } 
    public NamedIndexProp PropName { get { return _PropName; } } 
    internal DataType getter(IndexType ndx) 
    { 
     return ... 
    } 
    internal void Setter(IndexType ndx, DataType value) 
    { 
     ... = value; 
    } 
} 
+1

你需要添加一些解釋給你的答案,使其更好 – Ibo 2017-10-18 00:23:53

+0

很自我解釋,使用源盧克! – Doug 2017-10-18 03:00:15