8

私はこの機能を持っています:

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

この関数は次のように実行できますがFunc(1,2);、1 行目はOKで、2 行目は(コンパイル時に) BANGになります。

2 行目からスローされる例外は次のとおりです。

演算子「+」は、タイプ「T」および「T」のオペランドには適用できません

したがって、演算子のオーバーロードを作成する必要があります。さて、これまでのところとても良いです。

しかし、1行目はどうですか?にも動的キャストが必要ではありませんyか?

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

実行時に評価されることは理解していますが、C# コンパイラが+1 行目の演算子を受け入れるのはなぜですか (つまり、T が+何か他のものになる可能性があると誤って想定しています)。

4

2 に答える 2

7

最初の例では、を作成xするdynamicことで、実際にoperator+操作も動的にしました。これにより、 の型指定子が取り除かTれ、有効な がないxという苦情が取り除かれます。Toperator+

実行時に動的バインディングが発生し、2 つのオペランドを評価してoperator+使用できることを確認します。

算術演算子のオペランドがコンパイル時の型 dynamic を持つ場合、式は動的にバインドされます (§7.2.2)。この場合、式のコンパイル時の型は動的であり、以下で説明する解決は、コンパイル時の型が動的であるオペランドの実行時の型を使用して、実行時に行われます。

2 番目の例では、コンパイラは型を認識しており、単に結果を変数x + yに格納しています。dynamicのさらなる使用法はresult2動的にバインドされます。代入演算子の右側には動的操作がないため、これは理にかなっています。

動的な式が含まれていない場合、C# は既定で静的バインディングを使用します。つまり、構成式のコンパイル時の型が選択プロセスで使用されます。

于 2012-05-04T16:57:20.473 に答える
3

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

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

于 2012-05-04T16:55:07.893 に答える