如何在属性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)’之间的歧义

为什么这个含糊不清?

我认为有两个原因不应该含糊不清:

  1. IsConfused后没有IsConfused
  2. 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(); 

确保不存在歧义的唯一方法是禁止使用具有相同名称的方法和属性。