web-dev-qa-db-ja.com

C#の動的型が静的なのはなぜですか?

動的キーワードを読んでいると、[MSDN]の次の行が見つかりました(Type dynamicを使用(C#プログラミングガイド) ):

タイプは静的タイプですが、動的タイプのオブジェクトは静的タイプ検査をバイパスします。ほとんどの場合、タイプオブジェクトのように機能します。

上記の行の静的の意味は何ですか?それは静的型チェックをどのようにバイパスしますか?

57
slash shogdhe

これは静的型付けです:

string foo = "bar";

fooは文字列であるため、コンパイル時にエラーが発生します。

foo = 1;

varを使用しても、静的に型付けされます。

var foo = "bar";     // foo is now a string
foo = 1;             // still a compile time error

Dynamicキーワードを使用すると、型が静的ではなく、変更できるため、次のようになります。

dynamic foo = "bar";   
foo = 1;              // this is now fine.

さて、「型は静的型です」と書かれているのは、多くの動的言語(JavaScriptなど)では次のようなことができるためです。

var foo = { bar: 1 };

これにより、「bar」というプロパティを持つオブジェクトが作成され、これを行うことができます。

foo.la = 2;

fooのオブジェクトに新しいプロパティaddsを追加します。しかし、C#で同じトリックを試すと

dynamic foo = new SomeClassThatDoesntHaveABarProperty();
foo.bar = 2;          // runtime error

プロパティを削除することもできません。動的変数には任意の型を割り当てることができますが、それらの型自体を変更することはできません。

そのタイプの機能が必要な場合は、 ExpandoObject を確認してください。

説明のとおり、dynamicは多くの場合オブジェクトのように機能します。あなたはこれを行うことができます:

dynamic foo = new Foo();
foo = new Bar();

これと同じように:

object foo = new Foo();
foo = new Bar();

ただし、プロパティまたはメソッドを使用したい場合に違いがあります。ダイナミックで、これを行うことができます:

dynamic foo = new Foo();
foo.FooMethod();          // Note: You WILL get a runtime exception if foo doesn't have a FooMethod

しかし、オブジェクトの場合、これを行う必要があります。

object foo = new Foo();
((Foo)foo).FooMethod();    // Note: I HAVE to know the type at compile time here

コンパイル時にfooの型をFooの型にキャストできることがわかっている場合にのみ、これを行うことができますコンパイル時に、そして私がすでにそれを知っているなら、Fooの代わりにobjectをタイプとして使用することができます。

115
Matt Burland

これは、動的として宣言された変数は動的型のままであり、たとえばint型の変数に変更できないことを意味します。ただし、変数が保持するオブジェクトのタイプを変更できるため、この概念は無視されます。

変数は静的に型付けされるため、C#は強く型付けされた言語と見なされます。つまり、すべての変数が型指定され、C#コンパイラはコードで正しい型が使用されているかどうかを確認できます。ほとんどのスクリプト言語のような弱く型付けされた言語では、変数の型は動的です。それらは任意の値を保持できます。

1
T_D