猿问

为什么C#不实现索引属性?

我知道,我知道...埃里克·利珀特(Eric Lippert)对此类问题的回答通常类似于“,因为它不值得设计,实施,测试和记录它的成本 ”。


但是,我仍然需要一个更好的解释……我正在阅读有关C#4新功能的博客文章,并且在有关COM Interop的部分中,以下部分引起了我的注意:


顺便说一句,此代码使用了另一个新功能:索引属性(仔细研究Range之后的方括号。)但是,此功能仅适用于COM互操作;您不能在C#4.0中创建自己的索引属性。


好的,但是为什么呢?我已经知道并感到遗憾,因为无法在C#中创建索引属性,但是这句话让我重新考虑了一下。我可以看到实现它的几个很好的理由:


CLR支持它(例如,PropertyInfo.GetValue有一个index参数),所以很遗憾我们不能在C#中利用它

如文章所示(使用动态调度),它支持COM互操作

它在VB.NET中实现

已经可以创建索引器,即将索引应用于对象本身,因此将概念扩展到属性,保持相同的语法并仅替换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#中看到此功能吗?如果没有,为什么?


慕标琳琳
浏览 409回答 3
3回答

繁花不似锦

这是我们设计C#4的方式。首先,我们列出了可以考虑添加到该语言的所有可能功能。然后,我们将这些功能分类为“这很不好,我们绝对不能做”,“这太棒了,我们必须做”和“这很好,但这次我们不要做”。然后,我们查看了设计,实施,测试,记录,运送和维护“必须拥有”功能所需的预算,发现我们超出了预算100%。因此,我们将一堆东西从“必须拥有”存储桶移到了“不错拥有”存储桶。索引属性永远不在“必须拥有”列表的顶部附近。他们在“好”列表上的位置很低,并且在“坏主意”列表上调情。我们花在设计,实施,测试,记录或维护良好功能X上的每一分钟都是我们不能花在A,B,C,D,E,F和G等出色功能上的每一分钟。我们必须毫不留情地确定优先级,以便仅尽力而为。索引属性会很不错,但是不错的地方还差得远不能实际实现。

慕斯王

AC#索引器是一个索引属性。它是Item默认命名的(您可以从VB中引用它),并且可以根据需要使用IndexerNameAttribute对其进行更改。我不确定为什么要专门设计这种方式,但这似乎是故意的限制。但是,它与Framework Design Guidelines一致,后者确实建议使用非索引属性返回成员集合的可索引对象的方法。即“可索引”是一种类型的特征;如果可索引的方式不止一种,那么实际上应该将其分为几种类型。

MMMHUHU

因为您已经可以做到这一点,并且迫使您在OO方面进行思考,所以添加索引属性只会给语言带来更多干扰。而这是做另一件事的另一种方式。class Foo{&nbsp; &nbsp; public Values Values { ... }}class Values{&nbsp; &nbsp; public string this[int index] { ... }&nbsp; &nbsp;&nbsp;}foo.Values[0]我个人更希望看到做某事的单一方法,而不是十种方法。但这当然是一个主观意见。
随时随地看视频慕课网APP
我要回答