Strange (possibly wrong?) C# compiler behavior with method overloading and enums

前端 未结 2 1633
一向
一向 2020-12-11 02:44

today I discovered a very strange behavior with C# function overloading. The problem occurs when I have a method with 2 overloads, one accepting Object and the other accepti

2条回答
  •  北荒
    北荒 (楼主)
    2020-12-11 03:20

    It may be that you're not aware that there's an implicit conversion from a constant1 of 0 to any enum:

    Bar x = 0; // Implicit conversion
    

    Now, the conversion from 0 to Bar is more specific than the conversion from 0 to object, which is why the Foo(Bar) overload is used.

    Does that clear everything up?


    1 There's actually a bug in the Microsoft C# compiler which lets it be any zero constant, not just an integer:

    const decimal DecimalZero = 0.0m;
    
    ...
    Bar x = DecimalZero;
    

    It's unlikely that this will ever be fixed, as it could break existing working code. I believe Eric Lippert has a two blog posts which go into much more detail.

    The C# specification section 6.1.3 (C# 4 spec) has this to say about it:

    An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type and to any nullable-type whose underlying type is an enum-type. In the latter case the conversion is evaluated by converting to the underlying enum-type and wrapping the result (§4.1.10).

    That actually suggests that the bug isn't just in allowing the wrong type, but allowing any constant 0 value to be converted rather than only the literal value 0.

    EDIT: It looks like the "constant" part was partially introduced in the C# 3 compiler. Previously it was some constant values, now it looks like it's all of them.

提交回复
热议问题