アップデート:
System.Object
以下の回答は、拡張された場合に固有のようです。他のクラスを拡張する場合NullReferenceException
、VB にはありません。
この動作は、この接続の問題に記載されている理由により、設計によるものです。
VB では、変数がオブジェクトとして静的に型指定されていない場合に限り、オブジェクトで定義された拡張メソッドを呼び出すことができます。
その理由は、VB は遅延バインディングもサポートしているためです。Object として宣言された変数を呼び出すときに拡張メソッドにバインドすると、拡張メソッドを呼び出そうとしているのか、別の遅延バインディングを呼び出そうとしているのかが曖昧になります。同じ名前のバインドされたメソッド。
理論的には Strict On でこれを許可できますが、Option Strict の原則の 1 つは、コードのセマンティクスを変更してはならないということです。これが許可されている場合、Option Strict 設定を変更すると、別のメソッドへの暗黙の再バインドが発生し、実行時の動作がまったく異なる結果になる可能性があります。
例:
Imports System.Runtime.CompilerServices
Module Extensions
<Extension()> _
Public Function IsNull(ByVal obj As Object) As Boolean
Return obj Is Nothing
End Function
<Extension()> _
Public Function IsNull(ByVal obj As A) As Boolean
Return obj Is Nothing
End Function
<Extension()> _
Public Function IsNull(ByVal obj As String) As Boolean
Return obj Is Nothing
End Function
End Module
Class A
End Class
Module Module1
Sub Main()
' works
Dim someString As String = Nothing
Dim isStringNull As Boolean = someString.IsNull()
' works
Dim someA As A = Nothing
Dim isANull As Boolean = someA.IsNull()
Dim someObject As Object = Nothing
' throws NullReferenceException
'Dim someObjectIsNull As Boolean = someObject.IsNull()
Dim anotherObject As Object = New Object
' throws MissingMemberException
Dim anotherObjectIsNull As Boolean = anotherObject.IsNull()
End Sub
End Module
実際、変数が次のように静的に型指定されている場合、VB コンパイラは遅延バインディング呼び出しを作成しますObject
。
.locals init ([0] object exampleObject, [1] bool exists)
IL_0000: ldnull
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: ldnull
IL_0004: ldstr "IsNull"
IL_0009: ldc.i4.0
IL_000a: newarr [mscorlib]System.Object
IL_000f: ldnull
IL_0010: ldnull
IL_0011: ldnull
IL_0012: call
object [Microsoft.VisualBasic]Microsoft.VisualBasic.
CompilerServices.NewLateBinding::LateGet(
object,
class [mscorlib]System.Type,
string,
object[],
string[],
class [mscorlib]System.Type[],
bool[])
IL_0017: call object [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::NotObject(object)
IL_001c: call bool [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Conversions::ToBoolean(object)
IL_0021: stloc.1