W jaki sposób kompilator VB.NET wybiera, które rozszerzenie przeciążenia ma być uruchamiane?
Masz ciekawą osobliwość - pomyślał, że ktoś może pomóc.
Wynikało to z zabawy z typami dopuszczającymi unieważnienie z tego pytania:
Jak sprawdzić, czy obiekt jest dopuszczalny?
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
Spodziewałbym się, że oba wywołania IsNullable będą traktowane przez kompilator tak samo, ale tak nie jest. Wywołanie metody rozszerzenia używa innego przeciążenia do normalnego wywołania metody, nawet jeśli argument „a” pozostaje niezmieniony.
Moje pytanie brzmi: dlaczego? Co sprawia, że kompilator zmienia zdanie między dwoma połączeniami?
FTR: Używamy Visual Studio 2010, .NET Framework 4.