NibblyPig
NibblyPig

Reputation: 52922

Can anyone explain this interesting C# problem?

I hit a bizarre problem earlier which I have replicated in a new console application. I wonder, can anyone explain why this occurs?

    static void Main(string[] args)
    {
        DoSomething(0);

        Console.Read();
    }

    public static void DoSomething(int? value)
    {
        Console.WriteLine("Do Something int? called");
    }

    public static void DoSomething(MyEnum value)
    {
        Console.WriteLine("Do Something MyEnum called");
    }

    public static enum MyEnum : int
    {
        test

    }
}

You get an error on the DoSomething line:

Error 1 The call is ambiguous between the following methods or properties: 'DoSomething(int?)' and 'DoSomething(MyEnum)'

However if you change the zero to any other number, there is no such problem.

Upvotes: 9

Views: 311

Answers (3)

renjith r
renjith r

Reputation: 1

An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type.

Upvotes: 0

LukeH
LukeH

Reputation: 269278

This is because the literal 0 is implicitly convertible to any enum.

So in the first situation, the 0 is "equally" convertible to either int? or MyEnum. Neither conversion is "better" than the other so the compiler doesn't know which method you're expecting to call.

If you change the 0 to a 1 then it works because 1 is not implicitly convertible to MyEnum, so the only matching method is the one that takes an int? argument.

Upvotes: 8

Timwi
Timwi

Reputation: 66573

The C# language specification states that there is an implicit conversion from the integer literal 0 to any enum type:

13.1.3 Implicit enumeration conversions

An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type.

Therefore, any other integer literal can only convert to int? and is thus unambiguous; but the literal 0 is convertible to both int? and your enum.

It doesn’t matter which values are defined in your enum. Even if you have an enum like enum Test { Cats=7 }, the above still applies. Remember that all enums can have all values of their underlying integer types and are not restricted to the values actually declared.

Upvotes: 16

Related Questions