2012-05-04 5 views
8

は、私はこの機能を持っている:2行目はBANG(コンパイル時に)行くながらC#の動的な演算子ですか?

static void Func1<T>(T x, T y) 
{ 
    dynamic result = ((dynamic)x + y); //line 1 
    dynamic result2 = (x + y);   //line 2 
} 

このfuncがFunc(1,2);として実行することができますが、1行目は、OKです。

ライン2からスローされた例外は次のとおりです。

演算子「+」タイプ「T」のオペランドに適用することはできないと「T」

だから、私たちはオペレータを作成する必要があります過負荷。さて、これまでのところとても良い。

1行目はどうですか? yでも動的キャストが必要なのでしょうか?

((dynamic)x + (dynamic)y);

私はそれが実行時に評価されていることを理解するが、なぜC#コンパイラは、(すなわち、誤ってTが何か他のものに+ことができると仮定)行1で+オペレータを受け入れていますか?

+0

コードを実行した後の 'result'の値は何ですか?それは「3」か「12」ですか?私の推測では、文字列の連結を行っているということです。 – Servy

+1

@Servy: 'T'が' int'のときに文字列の連結を行うと思うのはなぜですか? – LukeH

答えて

7

最初の例では、xdynamicとすると、実質的にはoperator+の操作が動的になりました。これにより、タイプ指定子Txで取り除かれ、Tに有効なoperator+が含まれていないという苦情が取り除かれます。

実行時動的結合operator+を使用することができることを確実にするために2つのオペランドを発生し、評価する:

算術演算子のオペランドが動的コンパイル時の型を持っている場合、次いで式動的にバインドされています(7.2.2項)。この場合、式のコンパイル時の型は動的であり、コンパイル時の型の動的型を持つオペランドの実行時の型を使用して、以下に説明する解像度が実行時に発生します。 2番目の例では

、コンパイラがx + yのためのタイプを知っていて、単にdynamic変数に結果を格納しています。 result2のさらなる使用法は、動的にバインドされます。動的な表現が関与していない

、スタティックバインディングのC#のデフォルト、構成式のコンパイル時の型があることを意味する:代入演算子の右に動的な操作がないので、これは理にかなっています選択プロセスで使用されます。

+0

さらに、ジェネリックメソッドが制約なしで型固有の演算子を使用しようとする理由がわかりました。 – Tejs

+0

さて、数値型のようなものでは、算術演算を可能にする型制約を思いつくことはできません。 – user7116

+0

フレームワークのような特定の値型のオーバーロードを単純に行うのが好ましい方法だと思います。それ以外の場合、特定の型をそのような操作を実行させたい場合は、特定のインタフェースを実装してからそのインタフェースに制約するようにします。 – Tejs

3

dynamicは、基本的にコンパイラに「私がやっていることが合法であることを確認しようとしないでください、実行時になると確信しています。動的型の変数に対して実行しようとする操作はすべてコンパイルされます。動的変数に割り当てられた型が実際に操作を実装していない場合は、正常に実行されません。

両方とも動的である必要がない理由として、コンパイラは基本的にLValueで始まるシグネチャに一致する操作に関係するいずれかの型の演算子(静的メソッド)を見つけようとします。 LValueが動的であるため、コンパイラは、XがYと同じプレースホルダ型であり、Yに+演算子がないことがわかっていても、Xとして使用されるものに演算が存在すると仮定する必要があります。