タイプセーフなVB.NETを使用する場合、つまり、C#4の「動的」キーワードに相当するものはありOption Strict On
ますか?
8 に答える
VB.NET では Object に相当しますが、Option Strict Off
. Option Strict On
同等のものはありません。別の言い方をすれば、dynamicキーワードはOption Strict Off
同等の機能を C# にもたらします。
VB.NET には常に "動的" 機能が組み込まれており、当初は遅延バインディングと呼ばれていました。この構文は永久にサポートされていました:
Dim obj = new SomeComClass()
obj.DoSomething()
.NET および COM で実装されたコードに取り組み、後者が最も一般的に使用されました。C#のdynamicキーワードは、同じ機能を提供します。VB.NET バージョン 10 で変更されましたが、現在は DLR も使用しています。これにより、Python や Ruby などの言語実装への動的バインディングのサポートが追加されます。
構文はまったく同じで、As なしで Dim キーワードを使用します。ただし、 を使用する必要がOption Strict Off
ありOption Infer On
ます。その打撃を少し和らげることができます。動的バインディングを通知するために特定のキーワードを使用する C# が非常に良い動きであったことを示しています。Afaik VB.NET でそうするすべての要求は、まだ検討されていますが、計画されていません。
必要に応じOption Strict On
て、キーワードを使用しPartial Class
てコードの一部を別のソース ファイルに移動することが、おそらく最も効果的な方法です。
これは、VB が C# と同じ粒度を持たないことについて Basic が言っていることを示しています。リフレクションを使用して、実行時にメソッドを動的に呼び出す C# のコードがあります。
var listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);
私がこれを行っている理由は、"GetSomeData" が、それぞれが異なるデータを取得する多数のメソッドのいずれかである可能性があるためです。ここでどのメソッドを呼び出すかは、実行時にこのオブジェクトに渡される文字列パラメーターに依存するため、「GetSomeData」の値は実行時に異なります。
「GetSomeData」の署名は次のとおりです。
public List<SomeResultSetClass> GetSomeData()
呼び出された各メソッドは、何らかのList<T>
オブジェクトを返します。次に、listResult オブジェクトを Export という汎用メソッドに送信します。これは次のようになります。
void Export<T>(List<T> exportList, string filePath, byte fileType) where T: class;
ここで問題が発生します。Invoke は System.Object 型のオブジェクトを返します。もちろん、aList<T>
も System.Object ですが、公開されているインターフェイスは System.Object インターフェイスであり、IList インターフェイスではありません。Export メソッドを実行しようとすると、次のようになります。
myExportObj.Export(listResult, parms.filePath, parms.fileType);
コードはコンパイルに失敗します。エラーは次のとおりです。
The type arguments for method '...Export<T>...' cannot be inferred from the usage. Try specifying the type arguments explicitly.
結構です!!問題は、コンパイラが System.Object インターフェイスを見ているため、IList メタデータを見つけられないことです。List<T>
これで、新しい を作成してそれに割り当てることができますが、(List<Whatever>) listResult
それはそもそも動的呼び出しの目的を無効にします。
修正は次のように変更var
することdynamic
です:
dynamic listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);
動的はコンパイル時に静的型チェックをバイパスするため、コンパイル エラーは発生しません。次に、動的オブジェクトが Export メソッドに渡されると、DLR (動的言語ランタイム) は、オブジェクトを暗黙的にキャストしてメソッド シグネチャの要件を満たすことができるかどうかを確認します。もちろん、それは可能です。
これが C# での動作です。VB では、行は次のようになります。
Dim listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, Nothing)
Option Strict On を使用すると、予想どおり、この行によってコンパイラが混乱します。オフにすると、正常に動作します。つまり、VB では、行を含むモジュール全体の型チェッカーをオフにする必要があります。これほど細かい粒度はありません。
Option Infer On と Option Strict Off をオンにしても、非常に近いものが得られます。
レイト バインディング COM オブジェクトとタイプ セーフ ( Option Strict On
) を使用してメソッドとプロパティを処理する方法は十分にあります。これは、Microsoft.VisualBasic.Interaction.CallByName および System.Type.InvokeMember メソッドを使用する場合です。(または、別の「部分」ファイルを で作成しますOption Strict
) Off
。
しかし、VB.NET から遅延バインディングを使用してイベントを処理することは、C# の動的型の場合ほど簡単ではありません。VB.NET の Dynamic Events で、その「ハック」を確認できます。