C# には、object、var、および dynamic の 3 つの「一般的な」型があります (ただし、すべてが実際の型というわけではありません)。
物体
他の型と同様に、1 つの特別なルールを持つ実際の型: 型が継承されない場合は、objectから継承されます。このことから、すべての型はobjectから直接的または間接的に継承することになります。
強調: object は typeです。オブジェクトはobject型にすることができ、その型には ToString() などのメソッドがあります。すべてがobjectから継承されるため、すべてをobjectにアップキャストできます。オブジェクト参照にオブジェクトを代入すると、 ElephantがAnimalから継承するAnimal参照にElephantタイプのオブジェクトを代入するときと同じように、アップキャストが行われます。
SomeType x = new SomeType();
object obj = x;
obj.DoSomething();
- objはコンパイル時にobject型として扱われ、実行時にobject型になります (これは実際の型であるため論理的です - objはobjectとして宣言されているため、その型のみにすることができます)
- obj.DoSomething()は、SomeType にこのメソッドがあるかどうかに関係なく、 objectにこのメソッドがないため、コンパイル時エラーが発生します。
ヴァール
これは実際の型ではありません。単に「コンパイラ、割り当ての右側に基づいて型を見つけてください」の省略形です。
SomeType x = new SomeType();
var obj = x;
obj.DoSomething();
- objはコンパイル時にSomeType型として扱われ、"var" の代わりに "SomeType" を記述したかのように、実行時にSomeType型になります。
- SomeTypeにメソッドDoSomething()がある場合、このコードは機能します
- SomeTypeにメソッドがない場合、コードはコンパイル時エラーを引き起こします
動的
これは、変数のコンパイル時の型チェックを無効にするようにコンパイラに指示する型です。オブジェクトは、コンパイル時および実行時に動的な型を持つものとして扱われます。
SomeType x = new SomeType();
dynamic obj = x;
obj.DoSomething();
xがDoSomethingメソッドを持たない型の場合、これは例外をスローしますが、それを呼び出して、コンパイル時エラーなしでパラメーターとして任意のオブジェクトを渡すことは引き続き可能であり、それ自体のみを示すエラーが発生します。実行時、そしておそらく特定の状況でのみ - 潜在的なバグ。したがって、クラスの任意の種類のパブリック インターフェイスで動的を使用する場合は、リフレクションを使用して実行時に常に手動で型チェックを行うか、例外を慎重に処理するか、最初から型チェックを行わないようにする必要があります。
注: もちろん、参照されているオブジェクトの型が変わることはありません。objはobjectかもしれませんが、それが参照するxはまだSomeTypeです。