web-dev-qa-db-ja.com

拡張メソッドと動的オブジェクト

私の問題を次のコードスニペットに要約します。

List<int> list = new List<int>() { 5, 56, 2, 4, 63, 2 };
Console.WriteLine(list.First());

上記のコードは正常に機能しています。

今、私は次を試しました

dynamic dList = list;
 Console.WriteLine(dList.First());

しかし、RuntimeBinderExceptionを取得しています。なぜそうですか?

92
santosh singh

Stecyaの答えを拡張するために...拡張メソッドは、動的な型指定ではサポートされていません拡張メソッドの形式で、つまり、インスタンスメソッドであるかのように呼び出されます。ただし、これは機能します。

dynamic dList = list;
Console.WriteLine(Enumerable.First(dList));

もちろん、それは役に立つかもしれませんし、そうでないかもしれません。動的な型指定を使用する理由と方法に関する詳細情報を提供できる場合は、さらにサポートできる場合があります。

123
Jon Skeet

Jonの答えを拡張すると、これが機能しない理由は、通常の動的ではないコード拡張メソッドが、一致する拡張メソッドを持つ静的クラスのコンパイラーが認識しているすべてのクラスを完全に検索することで機能するためです。検索は、名前空間のネストと各名前空間で使用可能なusingディレクティブに基づいて順番に実行されます。

つまり、動的拡張メソッドの呼び出しを正しく解決するには、何らかの方法でDLRが実行時すべての名前空間の入れ子とusingディレクティブが何であったかを知る必要がありますソースコード。これらすべての情報を通話サイトにエンコードするための便利なメカニズムはありません。このようなメカニズムを発明することを検討しましたが、コストが高すぎてスケジュールリスクが大きすぎて価値がないと判断しました。

130
Eric Lippert

First()Listのメソッドではないためです。 Linq ExtensionでIEnumerable<>に定義されています

18
Stecya