How can there be ambiguity between a property gett

2020-04-02 06:55发布

I can't believe I've never come across this before, but why am I getting a compiler error for this code?

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);
    }
}

Here is the error message:

Ambiguity between 'FooBar.IsValid' and 'FooBar.IsValid(int)'

Why is this ambiguous?

I'm thinking there are two reasons it should not be ambiguous:

  1. There are no parenthases after IsConfused.
  2. There is no int argument for IsConfused.

Where is the ambiguity?

4条回答
家丑人穷心不美
2楼-- · 2020-04-02 07:30

There error is because it is ambiguous since it's declared using var. It could be:

bool isConfused = ambiguous.IsValid;

Or:

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

Using var requires the compiler to be able to infer the exact meaning, and in this case, there are two possibilities.

However, if you remove the var, you'll still get a (different) error, since you can't have two members with the same name, one a property, and one a method.

查看更多
做自己的国王
3楼-- · 2020-04-02 07:35

You would get an error that "FooBar already contains a definition for IsValid"

查看更多
相关推荐>>
4楼-- · 2020-04-02 07:53

It's confusing you would get that particular message, but it is not legal to have two members with the same name (excepting method overloading). Here your property and method have the same name. This is the same reason you can't have a property and an inner class with the same name. Fields, properties, methods, and inner classes are all members of the enclosing type and must have unique names.

查看更多
ら.Afraid
5楼-- · 2020-04-02 07:54

At first, it might seem that the compiler could always figure out whether you're calling the method or using the property -- after all, the method has parentheses after it, and the property doesn't.

That doesn't hold up, though. You can use a method without the parentheses:

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

Bar(Foo);

And you can use a property with parentheses:

Action MyProperty { get; set; }

MyProperty();

The only way to make sure there's no ambiguity is to disallow having a method and a property with the same name.

查看更多
登录 后发表回答