それらのどれも直接対処しない重要で微妙な問題があります。C#で型を検討するには、静的型と実行時型の 2つの方法があります。
静的型は、ソースコード内の変数の型です。したがって、これはコンパイル時の概念です。これは、開発環境で変数またはプロパティにカーソルを合わせるとツールチップに表示されるタイプです。
ヘルパージェネリックメソッドを記述して静的型を取得し、型推論で静的型を処理できるようにします。
Type GetStaticType<T>(T x) { return typeof(T); }
実行時タイプは、メモリ内のオブジェクトのタイプです。したがって、これは実行時の概念です。これは、GetType()メソッドによって返されるタイプです。
オブジェクトの実行時の型は、それを保持または返す変数、プロパティ、またはメソッドの静的な型とはしばしば異なります。たとえば、次のようなコードを使用できます。
object o = "Some string";
変数の静的型はですがobject、実行時に変数の参照先の型はstringです。したがって、次の行は「System.String」をコンソールに出力します。
Console.WriteLine(o.GetType()); // prints System.String
ただし、o開発環境で変数にカーソルを合わせると、タイプSystem.Object(または同等のobjectキーワード)が表示されます。上記のヘルパー関数を使用しても同じことがわかります。
Console.WriteLine(GetStaticType(o)); // prints System.Object
以下のような値型の変数についてはint、double、System.Guid、あなたは値の型が別の型の基底クラスとして使用することはできませんので、実行時の型は常に、静的な型と同じになることを知っています。値型は、継承チェーンの中で最も派生した型であることが保証されています。これは、封印された参照型にも当てはまります。静的な型が封印された参照型の場合、ランタイム値はその型のインスタンスまたはのいずれかでなければなりませんnull。
逆に、変数の静的型が抽象型の場合、静的型と実行時型が異なることが保証されます。
コードでそれを説明するには:
// int is a value type
int i = 0;
// Prints True for any value of i
Console.WriteLine(i.GetType() == typeof(int));
// string is a sealed reference type
string s = "Foo";
// Prints True for any value of s
Console.WriteLine(s == null || s.GetType() == typeof(string));
// object is an unsealed reference type
object o = new FileInfo("C:\\f.txt");
// Prints False, but could be true for some values of o
Console.WriteLine(o == null || o.GetType() == typeof(object));
// FileSystemInfo is an abstract type
FileSystemInfo fsi = new DirectoryInfo("C:\\");
// Prints False for all non-null values of fsi
Console.WriteLine(fsi == null || fsi.GetType() == typeof(FileSystemInfo));
int