Wie wählt der VB.NET-Compiler die auszuführende Erweiterungsüberladung aus?

Ich habe eine interessante Kuriosität - dachte, jemand könnte helfen.

Dies ergab sich aus einigem Spaß mit nullbaren Typen aus dieser Frage:

Wie überprüfe ich, ob ein Objekt nullbar ist?

Option Strict On

Module Test
  ' Call this overload 1
  <Extension()>
  Function IsNullable(obj As ValueType) As Boolean
    Return False
  End Function

  ' Call this overload 2
  <Extension()>
  Function IsNullable(Of T As {Structure})(obj As Nullable(Of T)) As Boolean
    Return True
  End Function

  Sub Test() 
    ' a is an integer!
    Dim a As Integer = 123

    ' calling IsNullable as an extension method calls overload 1 and returns false
    Dim result1 As Boolean = a.IsNullable()

    ' calling IsNullable as method calls overload 2 and returns true
    Dim result2 As Boolean = IsNullable(a)

    ' why? surely the compiler should treat both those calls as equivalent
  End Sub
End Module

Ich würde erwarten, dass beide Aufrufe von IsNullable vom Compiler gleich behandelt würden, aber das ist nicht der Fall. Der Erweiterungsmethodenaufruf verwendet eine andere Überladung als der normale Methodenaufruf, obwohl das Argument "a" unverändert bleibt.

Meine Frage ist warum? Was veranlasst den Compiler, seine Meinung zwischen den beiden Aufrufen zu ändern?

FTR: Wir verwenden Visual Studio 2010, .NET Framework 4.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage