为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
慕标琳琳 2019-11-28 09:51:49
我知道,我知道...埃里克·利珀特(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 Systempublic 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#中看到此功能吗?如果没有,为什么?
查看完整描述

3 回答

?
繁花不似锦

TA贡献1851条经验 获得超4个赞

这是我们设计C#4的方式。


首先,我们列出了可以考虑添加到该语言的所有可能功能。


然后,我们将这些功能分类为“这很不好,我们绝对不能做”,“这太棒了,我们必须做”和“这很好,但这次我们不要做”。


然后,我们查看了设计,实施,测试,记录,运送和维护“必须拥有”功能所需的预算,发现我们超出了预算100%。


因此,我们将一堆东西从“必须拥有”存储桶移到了“不错拥有”存储桶。


索引属性永远不在“必须拥有”列表的顶部附近。他们在“好”列表上的位置很低,并且在“坏主意”列表上调情。


我们花在设计,实施,测试,记录或维护良好功能X上的每一分钟都是我们不能花在A,B,C,D,E,F和G等出色功能上的每一分钟。我们必须毫不留情地确定优先级,以便仅尽力而为。索引属性会很不错,但是不错的地方还差得远不能实际实现。


查看完整回答
反对 回复 2019-11-28
?
慕斯王

TA贡献1864条经验 获得超2个赞

AC#索引器是一个索引属性。它是Item默认命名的(您可以从VB中引用它),并且可以根据需要使用IndexerNameAttribute对其进行更改。


我不确定为什么要专门设计这种方式,但这似乎是故意的限制。但是,它与Framework Design Guidelines一致,后者确实建议使用非索引属性返回成员集合的可索引对象的方法。即“可索引”是一种类型的特征;如果可索引的方式不止一种,那么实际上应该将其分为几种类型。


查看完整回答
反对 回复 2019-11-28
?
MMMHUHU

TA贡献1834条经验 获得超8个赞

因为您已经可以做到这一点,并且迫使您在OO方面进行思考,所以添加索引属性只会给语言带来更多干扰。而这是做另一件事的另一种方式。


class Foo

{

    public Values Values { ... }

}


class Values

{

    public string this[int index] { ... }    

}


foo.Values[0]

我个人更希望看到做某事的单一方法,而不是十种方法。但这当然是一个主观意见。


查看完整回答
反对 回复 2019-11-28
  • 3 回答
  • 0 关注
  • 408 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信