项目和此[] - 已声明具有相同名称的成员

时间:2011-07-15 21:05:51

标签: c# .net compiler-errors indexer

  

可能重复:
  Class with indexer and property named “Item”

刚刚遇到过我以前从未见过的东西,并想知道为什么会发生这种情况?

使用下面的类,我得到编译器错误“已经声明了具有相同名称的成员”,关于“Item”和“this [...]”。

public class SomeClass : IDataErrorInfo 
{
    public int Item { get; set; }

    public string this[string propertyName]
    {
        get
        {
            if (propertyName == "Item" && Item <= 0)
            {
                return "Item must be greater than 0";
            }
            return null;
        }
    }

    public string Error
    {
        get { return null; }
    }
}

编译器似乎认为此[...]和Item使用相同的成员名称。这是正确/正常吗?我很惊讶我以前没遇到过这个。

4 个答案:

答案 0 :(得分:7)

当您像这样定义索引器时:

this[string propertyName]

它被编译到.Item属性。

您可以使用[System.Runtime.CompilerServices.IndexerName("NEW NAME FOR YOUR PROPERTY")]属性将其修改为索引器。

答案 1 :(得分:6)

是的。 this[]默认情况下会编译为名为Item 的属性。您可以使用System.Runtime.CompilerServices.IndexerName属性更改它。 (MSDN link

答案 2 :(得分:2)

这很正常。 C#语言有关键字“this”,它用于声明索引器,但在编译的类中,索引器的get方法将被称为“get_Item”(这是.NET中的跨语言约定)。由于编译器希望为Item属性的getter赋予相同的名称,因此它会报告错误。

答案 3 :(得分:0)

如果你用IL代码查看IDataErrorInfo接口,你将会

.class public interface abstract auto ansi IDataErrorInfo
{
    .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = { string('Item') }
    .property instance string Error
    {
        .get instance string System.ComponentModel.IDataErrorInfo::get_Error()
    }

    .property instance string Item
    {
        .get instance string System.ComponentModel.IDataErrorInfo::get_Item(string)
    }

}

将C#转换为

public interface IDataErrorInfo
{
    // Properties
    string Error { get; }
    string this[string columnName] { get; }
}

所以原因是C#确实隐藏了这个语法背后的一些特殊方法名称,它与CLR使用的实际方法名称冲突。