刚刚遇到过我以前从未见过的东西,并想知道为什么会发生这种情况?
使用下面的类,我得到编译器错误“已经声明了具有相同名称的成员”,关于“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使用相同的成员名称。这是正确/正常吗?我很惊讶我以前没遇到过这个。
答案 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使用的实际方法名称冲突。