【问题标题】:overloading Item on collections在集合上重载项目
【发布时间】:2012-06-27 11:06:33
【问题描述】:

我有一个集合类MyCollection<T>

我已经实现了T this[string name],效果很好。

我也尝试实现T Item(string name),但当然会报错:

MyCollection<T> 类型已包含 Item 的定义

应该如此。但是我也想通过实现函数T Item(string, bool) 来重载Item,但这也会引发同样的错误。

为什么编译器会认为T Item(string, bool) 与索引器T Item(string) 发生冲突?如果它不是一个索引器而只是一个普通方法,那么这两个声明将是两个完全有效的重载。

【问题讨论】:

    标签: c# collections


    【解决方案1】:

    您绝对可以重载索引器 - 但不能使用名为 Item方法 重载它。要重载索引器,您只需要:

    public T this[string name, bool condition]
    {
        get { ... }
        set { ... }
    }
    

    编辑:好的,看起来像:

    • 不能有两个不同种类的成员(一个方法,一个属性)同名,根据 C# 4 规范的第 10.3 节,这是正确的
    • 您不能拥有索引器名称为 Item 的属性,这有点令人惊讶,因为它们都是底层属性

    如果您使用DefaultMemberAttribute 更改索引器属性的生成名称,我怀疑您可以在名为Item 的属性旁边拥有索引器,但我还没有尝试过。

    【讨论】:

    • 有趣的是,为什么不能使用 Indexer 声明一种方法,而不能使用普通方法声明一种方法。毕竟,编译后你会有 2 个完全不同的方法信号。据我所知,IL 在命名方面的限制更少,例如它确实允许 2 种方法仅在返回类型上有所不同(这在 C# 中是非法的)。那么,为什么这是不可能的,如果它可以在 IL 中完成,而在 C# 中是非法的?我可能会自己检查后者。
    • @Ravadre:目前尚不清楚您是在猜测 OP 做了什么,还是在猜测其他经验。如果这是真实的体验,可能值得将其作为一个单独的问题提出。
    • 我指的是OP帖子,但C#实际上不允许做的是声明索引器,如果你有Item方法,任何Item方法(也有不同的签名)。严格来说,最后的 OP 问题:“为什么编译器会认为 T Item(string, bool) 与索引器 T Item(string) 发生冲突?”您的回答虽然完全有效(+1)并没有回答这个问题,我认为这很有趣,并且是 OP 提出的。
    • @Ravadre:我相信它实际上会创建一个get_Item 方法,而是一个Item 属性。问题是您不能有两个不同类型的成员(例如,一种方法,一种属性)但名称相同。话虽如此,我只是未能引入一个名为 Item 的新属性,并添加了一个索引器......我希望它在 IL 中有效(其中索引器 is 是一个属性),但显然它不是有效的 C#。检查规格...
    • 这似乎是真的,而且因为 OP 还询问 why 而不仅仅是 how,因此宣传您的内容可能是个好主意以我的拙见写信给你的帖子。最好的祝福。 PS。签入 Ildasm,您对为索引器创建的方法和属性名称是正确的。
    猜你喜欢
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 2013-07-13
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    相关资源
    最近更新 更多