How does VB.NET compiler choose which extension overload to run?

后端 未结 2 474
Happy的楠姐
Happy的楠姐 2021-01-05 08:09

Got an interesting oddity - thought someone might be able to help.

This came out of some fun with nullable types from this question:

How to check if an obje

2条回答
  •  鱼传尺愫
    2021-01-05 08:51

    I think this is a bug, or at least a VB.NET "feature". (I'm just not sure which of VB.NET or C# is wrong.)

    I have tried in LINQPad 4 (because that's what I've got on the machine I'm using) and for C# I got False for both results, for every value type and enum except for Nullable types, of course.

    Whereas for VB.NET I get the False and True for all value types and enums, except for Nullable types, and ValueType and [Enum] which return False, False because you can't have a ValueType? or [Enum]?. With Option Strict Off, Object causes late binding, and fails at runtime to locate either overload, but the second result is False also because you can't have Object?.

    For completeness, Nullable types return True, True for both languages as expected.

    The fact that C# is doing something different (assuming my test is correct) confirms the reference to the C# "Better Conversion" check is wrong (or being misread at least - in that C# is not doing what is being interpreted as why VB.NET is doing what it is doing).

    However, I do agree that the issue is probably related to the implicit conversion to Nullable(Of T) existing and somehow being a higher priority to the implicit conversion to ValueType.

    Here's my LINQPad 4 "Query" (C# Program):

    void Main()
    {
        Test.test();
    }
    
    // Define other methods and classes here
    static class Test
    {
        static bool IsNullable(this ValueType obj)
        {
            return false;
        }
    
        static bool IsNullable(this T? obj) where T:struct
        {
            return true;
        }
    
        public static void test()
        {
            int x = 42;
    
            bool result1 = x.IsNullable();
            bool result2 = IsNullable(x);
    
            result1.Dump("result1");
            result2.Dump("result2");
        }
    }
    

提交回复
热议问题