2012-03-23 6 views
17

私が理解しているように、各言語はそれ自身のdynamicハンドラを持つことができるので、適切なルールが適用されます。次のことが正しいか間違っているかどうかはわかりません。思考?"ダイナミック"を使用するインターフェイスベースのメソッド呼び出しは、C#のメソッド解決ルールに従っている必要がありますか?

シナリオ2つのいくつかの方法とのインタフェース(一方が他方を実装):

public interface IA { 
    void Bar(object o); 
} 
public interface IB : IA { 
    void Foo(object o); 
} 

と基本的なインプリメンテーション:

public class B : IB { 
    public void Foo(object o) { Console.WriteLine("Foo"); } 
    public void Bar(object o) { Console.WriteLine("Bar"); } 
} 

次に、通常のC#(NO dynamic)と、我々がアクセスすることができますタイプIBのターゲットからIAの方法:

IB b = new B(); 
var o = new { y = "z" }; 
b.Foo(o.y); // fine 
b.Bar(o.y); // fine 

は、今度は、故意に全体のinvoke使用にdynamic処理を行い、引数、(それはここではありませんが、一般的なケースでとして、これは、オーバーロードの解決に影響を与える可能性がある)に、いくつかのdynamicを追加してみましょう。

IB b = new B(); 
dynamic x = new {y = "z"}; 
b.Foo(x.y); // fine 
b.Bar(x.y); // BOOM! 

失敗しますRuntimeBinderExceptionで:

'IB' は、それが私言う、今

'バー' の定義が含まれていません。 IBと全く同じではありませんBarメソッドを持っています。しかしながら、第1の例に示すように、通常のC#規則では、ターゲットの宣言型がインタフェース(IB)であるため、実装されることが知られている他のインタフェース(すなわちIA)が過負荷解決の一部としてチェックされる。

So:これはバグですか?または私はそれを誤解していますか?

+0

+1興味深い。私は、DLRがコンパイラ/ CLRとは対照的に、このようなことをあまりサポートしないのだろうかと思います。私はDLRがコールの解決を試みた責任があると思いますか? –

+0

@Adam私の理解では、リフレクションベースの呼び出しでは、言語固有のプロバイダがあります。つまり、Microsoft.CSharp.RuntimeBinder.Binder'という言語規約に従ってください。 –

+0

呼び出しを試みるクラスの継承と同じことを観察していますかベースメソッド? (継承されたインタフェースメソッドとは対照的に)。 –

答えて

6

これはバインダーのよく知られた制限事項であり、SOで数回程度尋ねられ、対象はthis feedback articleです。

これは、C#4.0出荷時に明示的に範囲を定めたものであり、私たちはこれを再訪したいと考えています。 ICollectionで実際に定義されているこの特定のケースのISet/IListメソッドは、親インターフェイスを掘り下げてもC#の動的バインディングの範囲を不必要に制限しない最も目立つ場所です。

この問題は現在、私たちのバグトリアージカットラインのすぐ下にありますが、すぐにこのようなサポートを追加したいと考えています。私たちは現在、Visual Studioの次のリリースでこの問題を修正するために追跡していないことを示すために「修正しない」という問題をマークしています。バグトリアージリストで期待以上に進んだ場合、または次のリリースでバグを再訪した場合、私たちは翌年にこのバグを再開します。

まだ起こっていないafaik。記事には多くの票がありません。

関連する問題