2010-07-20 73 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