如何在属性getter和带有一个参数的方法之间存在歧义?
我不敢相信我以前从未遇到过这个,但为什么我的代码会出现编译器错误?
public class Main { public Main() { var ambiguous = new FooBar(1); var isConfused = ambiguous.IsValid; // this call is ambiguous } } public class FooBar { public int DefaultId { get; set; } public FooBar(int defaultId) { DefaultId = defaultId; } public bool IsValid { get { return DefaultId == 0; } } public bool IsValid(int id) { return (id == 0); } }
这是错误消息:
‘FooBar.IsValid’和’FooBar.IsValid(int)’之间的歧义
为什么这个含糊不清?
我认为有两个原因不应该含糊不清:
- IsConfused后没有
IsConfused
。 -
IsConfused
没有int参数。
歧义在哪里?
有错误是因为它是模糊的,因为它是使用var
声明的。 它可能是:
bool isConfused = ambiguous.IsValid;
要么:
Func isConfused = ambiguous.IsValid;
使用var
要求编译器能够推断出确切的含义,在这种情况下,有两种可能性。
但是,如果删除var
,则仍会出现(不同)错误,因为您不能拥有两个具有相同名称的成员,一个属性和一个方法。
你会得到那个特定的消息是令人困惑的,但是有两个同名的成员是不合法的(除了方法重载)。 在这里,您的属性和方法具有相同的名称。 这与您不能拥有属性和具有相同名称的内部类的原因相同。 字段,属性,方法和内部类都是封闭类型的成员 ,并且必须具有唯一的名称。
您将收到“FooBar已包含IsValid定义”的错误
起初,似乎编译器总是可以确定你是在调用方法还是使用属性 – 毕竟,该方法后面有括号,而属性没有。
但这并没有成功。 您可以使用没有括号的方法:
void Foo() { ... } void Bar(Action action) { ... } Bar(Foo);
您可以使用带括号的属性:
Action MyProperty { get; set; } MyProperty();
确保不存在歧义的唯一方法是禁止使用具有相同名称的方法和属性。