ISetを呼び出す理由 .Contains() はコンパイルされますが、実行時に例外がスローされますか? 質問する

ISetを呼び出す理由 .Contains() はコンパイルされますが、実行時に例外がスローされますか? 質問する

以下の動作を説明するのを手伝ってください:

dynamic d = 1;
ISet<dynamic> s = new HashSet<dynamic>();
s.Contains(d);

コードはエラーや警告なしでコンパイルされますが、最後の行で次の例外が発生します。

Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.Collections.Generic.ISet<object>' does not contain a definition for 'Contains'
   at CallSite.Target(Closure , CallSite , ISet`1 , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
   at FormulaToSimulation.Program.Main(String[] args) in 

私の知る限り、これは動的オーバーロードの解決に関連していますが、奇妙なのは

(1) sの型が の場合HashSet<dynamic>、例外は発生しません。

(2)動的引数を受け入れるメソッドで非ジェネリックインターフェースを使用すると、例外は発生しません。

したがって、この問題は特にジェネリック インターフェイスに関連しているように見えますが、問題の原因を正確に特定することはできませんでした。

これはコンパイラ/型システムのバグですか、それとも正当な動作ですか?

ベストアンサー1

これまでに受け取った回答では、発生している動作は説明されていません。変数の静的型がinstead of でICollection<object>.Contains(object)あっても、DLR はメソッドを見つけて、ボックス化された整数をパラメーターとして呼び出す必要があります(前者は後者から派生しているため)。ISet<dynamic>ICollection<dynamic>

したがって、これはバグだと信じており、Microsoft Connect に報告しました。その行動が何らかの形で望ましいものであることが判明した場合、その旨のコメントがそこに投稿されます。

おすすめ記事