C#でdynamicとvarをオブジェクトにキャストする
これらの機能を考えてみましょう。
static void Take(object o)
{
Console.WriteLine("Received an object");
}
static void Take(int i)
{
Console.WriteLine("Received an integer");
}
このように Take
関数を呼び出すと。
var a = (object)2;
Take(a);
オブジェクトを受け取りました。
しかし、このように呼び出すと
dynamic b = (object) 2;
Take(b);
というメッセージが表示されます。
両方のパラメータ (a
& b
) は object
にキャストされます。しかし、なぜコンパイラはこのような動作をするのでしょうか?
52
3
var` は,RHS で型を決定させるための構文上の糖に過ぎない.
あなたのコードでは
が相当します。
オブジェクトに
2
をボックス化したので、オブジェクトを取得します。dynamic` については、[Using Type dynamic]を参照するとよいでしょう。なお、型は静的型ですが、dynamic型のオブジェクトは静的型チェックをバイパスします、つまり、ofで指定した型です。
はバイパスされ、実行時にその本当の型が解決されます。
実行時にどのように解決されるかについては、私はあなたが想像しているよりもずっと複雑だと思います。
例えば、次のようなコードがあったとします。
で、回答の後ろにフルIL(デバッグ設定の)を付けました。
この2行について
はILのみです。
しかし、この2つについては
は
TestMethod
のIL_000f
からIL_007a
までです。これはTake(object)
やTake(int)
を直接呼び出すのではなく、このようにメソッドを呼び出しています。TestClass` の完全な IL です。
ダイナミックな
1.dynamic
は
Dynamically typed` です。 2.Dynamically typed - これは、宣言された変数の型が、実行時にコンパイラによって決定されることを意味します。var:
1.var
は
Static typed` です。 2.静的型付け - これは、宣言された変数の型がコンパイル時にコンパイラによって決定されることを意味します。これによって、
dynamic
では実行時にOverloadの解決が行われることがわかります。従って、変数
b
はint
として保持されます。これが
Take(b);
がTake(int i)
を呼び出す理由です。しかし、
var a = (object)2
の場合、変数a
は 'object' として保持されます。これが、Take(a); が
Take(object o)
を呼び出す理由です。最初のケースでは、var はオブジェクトを意味するので、
Take(object o)
が呼び出されます。2 番目のケースではdynamic
型を使用しており、int
をボックス化したにもかかわらず、int
型という情報を持っているので、最適なメソッドが呼び出されます。