我知道,我知道... 埃里克 · 利伯特对这类问题的回答通常是“ 因为它不值得设计、实现、测试和记录它的成本”。
但是,我仍然想要一个更好的解释... ... 我正在阅读 这篇关于 C # 4新特性的博文,在 COM 互操作部分,以下部分引起了我的注意:
顺便说一下,这段代码使用了另一个新特性: 索引属性(仔细查看 Range 后面的那些方括号)但是这个特性只适用于 COM 互操作; 您不能在 C # 4.0中创建自己的索引属性.
好吧,但是为什么?我已经知道并且很遗憾不能在 C # 中创建索引属性,但是这个句子让我重新思考它。我可以找到几个很好的理由来实施它:
PropertyInfo.GetValue
有一个 index
参数) ,所以很遗憾我们不能在 C # 中利用它this
,可能没什么大不了的它允许写这样的东西:
public class Foo
{
private string[] _values = new string[3];
public string Values[int index]
{
get { return _values[index]; }
set { _values[index] = value; }
}
}
目前我所知道的唯一解决办法是创建一个实现索引器的内部类(例如 ValuesCollection
) ,并更改 Values
属性,使其返回该内部类的一个实例。
这是非常容易做到的,但恼人... 所以也许编译器可以为我们做到这一点!一个选项是生成一个实现索引器的内部类,并通过一个公共泛型接口公开它:
// interface defined in the namespace System
public interface IIndexer<TIndex, TValue>
{
TValue this[TIndex index] { get; set; }
}
public class Foo
{
private string[] _values = new string[3];
private class <>c__DisplayClass1 : IIndexer<int, string>
{
private Foo _foo;
public <>c__DisplayClass1(Foo foo)
{
_foo = foo;
}
public string this[int index]
{
get { return _foo._values[index]; }
set { _foo._values[index] = value; }
}
}
private IIndexer<int, string> <>f__valuesIndexer;
public IIndexer<int, string> Values
{
get
{
if (<>f__valuesIndexer == null)
<>f__valuesIndexer = new <>c__DisplayClass1(this);
return <>f__valuesIndexer;
}
}
}
但是当然,在这种情况下,属性 事实上将返回一个 IIndexer<int, string>
,并且不会真正成为一个索引属性... ... 最好生成一个真正的 CLR 索引属性。
您认为如何? 您想在 C # 中看到这个特性吗? 如果不想,为什么?