13

我不敢相信我以前从未遇到过这种情况,但为什么我会收到此代码的编译器错误?

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
  2. 没有 int 参数IsConfused

歧义在哪里?

4

4 回答 4

16

有错误是因为它是模棱两可的,因为它被声明为 using var。它可能是:

bool isConfused = ambiguous.IsValid;

或者:

Func<int, bool> isConfused = ambiguous.IsValid;

使用var要求编译器能够推断出确切的含义,在这种情况下,有两种可能。

但是,如果您删除var,您仍然会收到一个(不同的)错误,因为您不能有两个具有相同名称的成员,一个是属性,一个是方法。

于 2011-07-07T19:43:58.567 回答
6

您会收到该特定消息会令人困惑,但是拥有两个同名成员是不合法的(方法重载除外)。在这里,您的属性和方法具有相同的名称。这与您不能拥有同名的属性和内部类的原因相同。字段、属性、方法和内部类都是封闭类型的成员,并且必须具有唯一的名称。

于 2011-07-07T19:43:50.943 回答
0

您将收到“FooBar 已包含 IsValid 的定义”的错误消息

于 2011-07-07T19:45:15.480 回答
-1

起初,编译器似乎总能判断出你是在调用方法还是使用属性——毕竟,方法后面有括号,而属性没有。

不过,这不成立。您可以使用不带括号的方法:

void Foo() { ... }
void Bar(Action action) { ... }

Bar(Foo);

您可以使用括号的属性:

Action MyProperty { get; set; }

MyProperty();

确保没有歧义的唯一方法是禁止使用同名的方法和属性。

于 2011-07-07T19:46:52.780 回答