【问题标题】:"Item" property along with indexer“项目”属性以及索引器
【发布时间】:2013-06-20 14:06:02
【问题描述】:

我已经阅读了Class with indexer and property named "Item" 的答案,但他们没有解释为什么我可以有一个具有多个索引器的类,它们都创建了Item 属性和get_Item/set_Item 方法(当然工作好吧,因为它们是不同的重载),但我不能有明确的 Item 属性。

考虑代码:

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
        }

        public int this[string val]
        {
            get
            {
                return 0;
            }
            set
            {
            }
        }

        public string this[int val] //this is valid
        {
            get
            {
                return string.Empty;
            }
            set
            {
            }
        }

        public int Item { get; set; } //this is not valid
    }
}

对于两个索引器,创建了四个方法:

Int32 get_Item(String val)
Void set_Item(String val, Int32 value)
String get_Item(Int32 val)
Void set_Item(Int32 val, String value)

我希望我的财产能够创建

Int32 get_Item()
Void set_Item(Int32 value)

这些重载通常是可以接受的,但不知何故编译器不允许我创建这样的属性。

请注意,我不需要重命名索引器等的方法,这是已知的 - 我需要解释。这个答案:https://stackoverflow.com/a/5110449/882200 没有解释为什么我可以有多个索引器。

【问题讨论】:

  • 我怀疑如果您要将Item 属性的返回类型更改为intstring 以外的其他值,它会编译,但事实并非如此。如果您在 class/struct 中声明索引器,编译器似乎不允许您拥有显式的 Item 属性。谁知道为什么?这很奇怪。

标签: c# properties indexer


【解决方案1】:

出于同样的原因,以下内容无法编译:

public class Test
{
    public int Foo
    {
        get;
        set;
    }

    public void Foo()
    {
        return;
    }
}

上面的结果是“'Test' 类型已经包含 'Foo' 的定义”。尽管这些可以实现为 Foo() 方法和 get_Foo() 方法,但命名是一个实现细节 - 在语言级别,它是 .Foo() 和 .Foo 并且由于并非所有语言都支持它,编译器认为这是一个错误。

同样,其他语言可能不支持具有同名的索引器和属性。因此,尽管您指出此可以编译为 get_Item() 和 get_Item(Int32),但 CLR 设计者仍然选择不允许它。尽管 CLR 可以 被设计为允许这样做,但它可能在语言级别不受支持,因此他们选择避免​​任何此类问题。

【讨论】:

  • 好的,我明白你的意思,C# 并不是唯一的语言。但是多个索引器呢?我发现很难理解如何更容易实现多个索引器而不是索引器 + 属性...
  • CLR 允许“具有相同名称的两个方法”。 CLR 允许“具有相同名称的两个索引器”。您所说的是“一个属性和一个同名的索引器”,CLR 不允许这样做,因为他们不想假设语言会支持它。正如我试图解释的那样,CLR 通常认为重载两个相同类型的“事物”(例如索引器)是可以的,但命名两个 不同 类型的事物(例如属性和indexer) 同名是不行的。
  • @Chris:我不确定它是否是根据 ECMA 335 的 CLR 限制。例如,在 §I.10.3.2 中,索引器和属性用相同的名称“属性”和“只能根据参数的数量和类型(...)来重载属性和方法”。而通常的属性有这个数字 0,索引器 - 大于零。另一方面,那里涵盖了您的示例的推理。所以我想这是相当 C# 的限制。
  • 已经检查了两个规范,它看起来确实是 C# 问题。 CLR 本身没有索引器的概念(它们只是带有参数的属性),方法重载将允许 get_Item() 和 get_Item(Int32)。但是,根据 C# 规范,除非明确允许,否则两个事物不能具有相同的名称。允许方法重载;允许属性重载;允许索引器重载;并且允许构造函数重载。不允许其他组合(属性和属性、方法和构造函数、方法和属性、属性和索引器)。
猜你喜欢
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
  • 2020-03-18
  • 2013-06-16
相关资源
最近更新 更多