2017-02-24 14 views
3

関数を呼び出してパラメータの1つをdynamicに置き換えると、コンパイラは関数の結果を動的であると推定します。なぜこのようなことが起こるのか分かりません。動的関数パラメータを使用したC#コンパイラ型の推論

public string MethodWithoutOverloads(string a, string b) { ... } 

誰かがなぜタイプを知っている...

dynamic b = ""; 
var a = MethodWithoutOverloads("", b); 
a.DoesNotExist(); 

例:のための推論された型が動的であるので、このコードはコンパイルが、もちろんRuntimeBinderExceptionと、実行時に失敗します関数の戻り値の型ではないと推測されますか?

EDIT:コンパイラはメソッドが実行時に呼び出されることになるだろう知っていないので明確な、これが過負荷

答えて

1

あなたは正しい意味でのコンパイラはすべてString.Formatのオーバーロードがstringを返すので、aは関係なく、本当に何であるかb文字列でない必要があることを推測すること理由アウトできることです。

真実は、コンパイラがそれをしないということです。これは一般的なケースを解決しています。また、異なる戻り値の型を持つオーバーロードがC#で有効であるため、戻り値の型を動的に割り当てるだけで、ランタイムがそれを把握することができます。

public string MethodWithoutOverloads(string a, string b) { ... } 
dynamic a = ""; 
var result = MethodWithoutOverloads(a, a); // result is dynamic. 

は、コンパイラが resultstringであると判断を想像して、野生の西、あなたのライブラリに公開することができます、あなたの特定の質問に答えます。その後、後に、次の署名を使用して過負荷を追加することを決定した:

public int MethodWithoutOverloads(int a, int b) { ... } 

resultの種類は何をすべきですか?そして、resultに依存する既存のコードは、強く型付きされてstringになりますか?

string result = MethodWithoutOverloads(someDynamicVariable, someOtherDynamicVariable); 

セマンティクスは完全に変更されます。消費者が厳密に型指定された変数を持つ前に、実行時に突然潜んでしまう可能性のある安全でない潜在的なキャストが突然発生しました。

0

なし方法で発生させるように編集。例えば

、次の2つの方法を持っていることがあります。

int MyMethod(int a) 
{ 
    return 5; 
} 

double MyMethod(string a) 
{ 
    return 6.0; 
} 

をそして、あなたは以下のコードを記述します。

dynamic myThing = 5; 
var myResult = MyMethod(myThing); 

我々は明示的myThingダイナミックであり、このその言った考えます実行時に型を決定する場合、どのメソッドが呼び出されるかはわかりません(存在する場合)。したがって、戻り値の型もわかりません。

+0

これは、1つの方法、つまりあいまいさがない場合に発生します。 String.Formatは良い例ではありませんが、あいまいさがないときに独自のメソッドを呼び出すと型の推論も失敗します。 – Lev

+1

@Levそれは正しいです。*技術的に*コンパイラはあいまいさなくそれを理解することができるかもしれませんが、一見あまり得策ではないが、もっと多くの作業が必要になると思います。 'dynamic'が式の一部であるときはいつでも、結果は' dynamic'でもあります。あなたが型を知っていると確信しているならば、 'var'を使うのではなく変数型を明示的に明示してください。 – Rob

+0

これは基本的に"この場合の型推論を実装しませんでした "... – Lev

関連する問題