我知道,我知道...... Eric Lippert对这类问题的回答通常是" 因为它不值得设计,实施,测试和记录它的成本 ".
但是,我还是想要一个更好的解释......我正在阅读关于新C#4功能的博客文章,在关于COM Interop的部分中,以下部分引起了我的注意:
顺便说一句,这段代码使用了另外一个新功能:索引属性(仔细查看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; }
}
}
Run Code Online (Sandbox Code Playgroud)
目前我知道的唯一解决方法是创建一个ValuesCollection实现索引器的内部类(例如),并更改Values属性以便它返回该内部类的实例.
这很容易做到,但很烦人......所以也许编译器可以为我们做!一个选项是生成一个实现索引器的内部类,并通过公共通用接口公开它:
// interface defined in the namespace System
public interface IIndexer<TIndex, TValue>
{
TValue this[TIndex index] { get; set; }
}
public …Run Code Online (Sandbox Code Playgroud) 在C#中,我发现索引属性非常有用.例如:
var myObj = new MyClass();
myObj[42] = "hello";
Console.WriteLine(myObj[42]);
Run Code Online (Sandbox Code Playgroud)
但据我所知,没有语法糖支持自己支持索引的字段(如果我错了请纠正我).例如:
var myObj = new MyClass();
myObj.field[42] = "hello";
Console.WriteLine(myObj.field[42]);
Run Code Online (Sandbox Code Playgroud)
我需要这样做的原因是,我已经用我的分类的索引属性,但我 GetNumX(),GetX()和SetX()功能如下:
public int NumTargetSlots {
get { return _Maker.NumRefs; }
}
public ReferenceTarget GetTarget(int n) {
return ReferenceTarget.Create(_Maker.GetReference(n));
}
public void SetTarget(int n, ReferenceTarget rt) {
_Maker.ReplaceReference(n, rt._Target, true);
}
Run Code Online (Sandbox Code Playgroud)
你可能会看到将这些暴露为一个可索引的字段属性会更有意义.我可以编写一个自定义类来实现这一点,每次我想要语法糖,但所有的样板代码似乎都没有必要.
所以我编写了一个自定义类来封装样板,并且可以轻松创建可以编制索引的属性.这样我可以添加一个新属性,如下所示:
public IndexedProperty<ReferenceTarget> TargetArray {
get {
return new IndexedProperty<int, ReferenceTarget>(
(int n) => GetTarget(n),
(int n, ReferenceTarget rt) => SetTarget(n, …Run Code Online (Sandbox Code Playgroud) 假设我在类中有一个数组或任何其他集合,以及一个返回它的属性,如下所示:
public class Foo
{
public IList<Bar> Bars{get;set;}
}
Run Code Online (Sandbox Code Playgroud)
现在,我可以这样写:
public Bar Bar[int index]
{
get
{
//usual null and length check on Bars omitted for calarity
return Bars[index];
}
}
Run Code Online (Sandbox Code Playgroud)