C# GetType()の使い方を初心者向けに解説|typeof・isとの違いと型判定の注意点

はじめに

C#でプログラムを書いていると、「この変数は何の型なのか知りたい」「オブジェクトの実際のクラスを確認したい」という場面があります。そんなときに使えるのがGetType()メソッドです。

GetType()を使うと、文字列、数値、自作クラス、配列、Listなど、オブジェクトの実行時の型情報を取得できます。特に、object型の変数にさまざまな値が入る場合や、継承関係のあるクラスを扱う場合に役立ちます。

一方で、C#にはtypeofisといった型に関する機能もあります。これらは似ているように見えますが、使い方や判定の意味が異なります。初心者のうちは、GetType()typeofisの違いで混乱しやすいので、それぞれの役割を整理して理解することが大切です。

この記事では、C#のGetType()の基本的な使い方から、typeofisとの違い、型判定の注意点、リフレクションとの関係まで、初心者向けにわかりやすく解説します。

1. C#のGetType()とは?初心者向けに基本を解説

1-1. GetType()はオブジェクトの実行時の型を取得するメソッド

C#のGetType()は、オブジェクトが実行時にどの型であるかを取得するためのメソッドです。

たとえば、次のようなコードがあります。

C#
string name = "Taro";

Console.WriteLine(name.GetType());

実行結果は次のようになります。

C#
System.String

この例では、nameという変数に入っている値がstring型であることがわかります。

GetType()のポイントは、変数の宣言上の型ではなく、実際に入っているオブジェクトの型を取得することです。

C#
object value = "Hello";

Console.WriteLine(value.GetType());

実行結果は次のようになります。

C#
System.String

変数valueの宣言はobject型ですが、実際に入っている値は文字列なので、GetType()System.Stringを返します。

1-2. GetType()で取得できるType型とは

GetType()の戻り値はType型です。

C#
string text = "Hello";

Type type = text.GetType();

Console.WriteLine(type);

Type型は、型に関する情報を表すクラスです。たとえば、型名、名前空間、プロパティ、メソッド、フィールドなどの情報を取得できます。

C#
string text = "Hello";
Type type = text.GetType();

Console.WriteLine(type.Name);
Console.WriteLine(type.FullName);
Console.WriteLine(type.Namespace);

実行結果の例は次のとおりです。

C#
String
System.String
System

Type型を使うことで、単に「文字列型かどうか」を確認するだけでなく、その型が持つ構造的な情報も調べられます。

1-3. GetType()を使う場面と役割

GetType()は、主に次のような場面で使われます。

デバッグ時に変数の実際の型を確認したい場合。

C#
object data = 123;

Console.WriteLine(data.GetType());

型によって処理を分けたい場合。

C#
object value = "Hello";

if (value.GetType() == typeof(string))
{
Console.WriteLine("文字列です");
}

継承関係のあるクラスで、実際の派生クラスを確認したい場合。

C#
Animal animal = new Dog();

Console.WriteLine(animal.GetType());

リフレクションを使って、プロパティやメソッドの情報を取得したい場合。

C#
Type type = user.GetType();

foreach (var property in type.GetProperties())
{
Console.WriteLine(property.Name);
}

このように、GetType()は「実行時の型情報を知る」ための基本的なメソッドです。

1-4. GetType()はSystem.Objectに定義されている

C#のすべての型は、最終的にSystem.Objectを継承しています。GetType()はこのSystem.Objectに定義されているメソッドです。

そのため、ほとんどのオブジェクトでGetType()を呼び出すことができます。

C#
int number = 10;
string text = "Hello";
DateTime today = DateTime.Now;

Console.WriteLine(number.GetType());
Console.WriteLine(text.GetType());
Console.WriteLine(today.GetType());

実行結果の例は次のとおりです。

C#
System.Int32
System.String
System.DateTime

intのような値型でも、stringのような参照型でも、GetType()を呼び出せます。

ただし、nullに対してGetType()を呼び出すことはできません。この点は後ほど詳しく解説します。

2. C# GetType()の基本的な使い方

2-1. GetType()の基本構文

GetType()の基本構文は次のとおりです。

C#
変数.GetType()

戻り値はType型です。

C#
Type type = 変数.GetType();

具体例を見てみましょう。

C#
string message = "Hello C#";

Type type = message.GetType();

Console.WriteLine(type);

実行結果は次のようになります。

C#
System.String

GetType()はメソッドなので、末尾に必ず()を付けます。

C#
message.GetType()

初心者のうちは、GetTypeと書いてしまいがちですが、正しくはGetType()です。

2-2. 文字列・数値・クラスで型を取得する例

文字列の型を取得する例です。

C#
string text = "ABC";

Console.WriteLine(text.GetType());

実行結果は次のようになります。

C#
System.String

数値の型を取得する例です。

C#
int number = 100;
double price = 123.45;

Console.WriteLine(number.GetType());
Console.WriteLine(price.GetType());

実行結果は次のようになります。

C#
System.Int32
System.Double

自作クラスの型を取得する例です。

C#
class User
{
public string Name { get; set; }
}

class Program
{
static void Main()
{
User user = new User();

Console.WriteLine(user.GetType());
}
}

実行結果の例は次のようになります。

C#
User

名前空間を定義している場合は、名前空間を含んだ型名が表示されることがあります。

C#
MyApp.Models.User

2-3. GetType().Nameで型名を取得する

GetType()で取得したType型には、型名だけを取得するためのNameプロパティがあります。

C#
string text = "Hello";

Console.WriteLine(text.GetType().Name);

実行結果は次のようになります。

C#
String

intの場合は次のようになります。

C#
int number = 10;

Console.WriteLine(number.GetType().Name);

実行結果は次のとおりです。

C#
Int32

C#ではintと書きますが、.NETの正式な型名はSystem.Int32です。そのため、GetType().NameではInt32と表示されます。

よく使うC#の型名と、GetType().Nameで取得される名前は次のように対応します。

C#の型名GetType().Name
stringString
intInt32
longInt64
doubleDouble
boolBoolean
DateTimeDateTime

型名だけを表示したい場合は、GetType().Nameを使うと便利です。

2-4. GetType().FullNameで名前空間を含む型名を取得する

型名だけではなく、名前空間を含む完全な型名を取得したい場合はFullNameを使います。

C#
string text = "Hello";

Console.WriteLine(text.GetType().FullName);

実行結果は次のようになります。

C#
System.String

自作クラスでも確認してみましょう。

C#
namespace MyApp.Models
{
class User
{
public string Name { get; set; }
}
}

class Program
{
static void Main()
{
var user = new MyApp.Models.User();

Console.WriteLine(user.GetType().Name);
Console.WriteLine(user.GetType().FullName);
}
}

実行結果は次のようになります。

C#
User
MyApp.Models.User

Nameはクラス名だけ、FullNameは名前空間を含む型名です。

クラス名が同じでも名前空間が違う場合があります。そのような場合は、FullNameを使うことで型をより正確に識別できます。

2-5. GetType().NamespaceやAssemblyで取得できる情報

GetType()で取得できるType型には、NameFullName以外にも便利なプロパティがあります。

Namespaceは、型が属している名前空間を取得します。

C#
string text = "Hello";

Console.WriteLine(text.GetType().Namespace);

実行結果は次のようになります。

C#
System

Assemblyは、その型が含まれているアセンブリ情報を取得します。

C#
string text = "Hello";

Console.WriteLine(text.GetType().Assembly);

実行結果は環境によって異なりますが、System.Stringが含まれるアセンブリ情報が表示されます。

自作クラスの場合も同じように確認できます。

C#
User user = new User();

Type type = user.GetType();

Console.WriteLine(type.Name);
Console.WriteLine(type.FullName);
Console.WriteLine(type.Namespace);
Console.WriteLine(type.Assembly);

これらの情報は、通常の業務コードでは頻繁に使うものではありませんが、ライブラリ開発やリフレクションを使う場面では役立ちます。

3. GetType()を使った型判定の方法

3-1. GetType()で型が一致するか比較する

GetType()は、型が一致しているかどうかを判定するためにも使えます。

C#
object value = "Hello";

if (value.GetType() == typeof(string))
{
Console.WriteLine("string型です");
}

実行結果は次のようになります。

C#
string型です

GetType()は実際のオブジェクトの型を取得し、typeof(string)string型そのものを表します。

この2つを==で比較することで、型が完全に一致するかどうかを判定できます。

3-2. GetType() == typeof()で型を判定する

GetType()を使った型判定でよく見る形が、次の書き方です。

C#
value.GetType() == typeof()

たとえば、値がint型かどうかを判定する場合は次のようになります。

C#
object value = 100;

if (value.GetType() == typeof(int))
{
Console.WriteLine("int型です");
}

実行結果は次のとおりです。

C#
int型です

double型かどうかを判定する場合は次のように書きます。

C#
object value = 12.5;

if (value.GetType() == typeof(double))
{
Console.WriteLine("double型です");
}

このように、GetType()typeof()を組み合わせることで、実行時の型が特定の型と完全に一致するかどうかを判定できます。

3-3. if文で型ごとに処理を分けるサンプル

GetType()を使うと、型ごとに処理を分けることができます。

C#
object value = "Hello";

if (value.GetType() == typeof(string))
{
Console.WriteLine("文字列として処理します");
}
else if (value.GetType() == typeof(int))
{
Console.WriteLine("整数として処理します");
}
else if (value.GetType() == typeof(double))
{
Console.WriteLine("小数として処理します");
}
else
{
Console.WriteLine("その他の型です");
}

実行結果は次のようになります。

C#
文字列として処理します

ただし、このような型判定を多用すると、コードが複雑になりやすいです。型ごとに処理を分けたい場合でも、ポリモーフィズムやインターフェースを使ったほうが自然な設計になることがあります。

簡単なデバッグや一時的な分岐であればGetType()は便利ですが、本格的な設計では使いすぎに注意しましょう。

3-4. switch文・パターンマッチングと組み合わせる考え方

C#では、型ごとに処理を分ける場合、switch文やパターンマッチングを使う方法もあります。

GetType()を使った例です。

C#
object value = 100;

switch (value.GetType().Name)
{
case "String":
Console.WriteLine("文字列です");
break;

case "Int32":
Console.WriteLine("整数です");
break;

default:
Console.WriteLine("その他の型です");
break;
}

ただし、型名を文字列で比較する方法はあまりおすすめできません。

C#では、次のようにパターンマッチングを使うほうが自然です。

C#
object value = 100;

switch (value)
{
case string text:
Console.WriteLine($"文字列です: {text}");
break;

case int number:
Console.WriteLine($"整数です: {number}");
break;

case double d:
Console.WriteLine($"小数です: {d}");
break;

default:
Console.WriteLine("その他の型です");
break;
}

この書き方では、型判定と同時に変数へ代入できます。

GetType()は「完全にその型かどうか」を調べたいときに向いています。一方で、型ごとに処理を分けたいだけなら、isやパターンマッチングのほうが読みやすいことが多いです。

3-5. 型名の文字列比較は避けるべき理由

型判定で次のようなコードを書くことがあります。

C#
if (value.GetType().Name == "String")
{
Console.WriteLine("文字列です");
}

このコードは動作しますが、基本的にはおすすめできません。

理由は、型名を文字列で比較すると、タイプミスに弱くなるからです。

C#
if (value.GetType().Name == "Strng")
{
Console.WriteLine("文字列です");
}

このように間違えても、コンパイルエラーにはなりません。実行して初めて想定どおりに動かないことに気づきます。

一方、typeofを使えば、型名の間違いはコンパイル時に検出されます。

C#
if (value.GetType() == typeof(string))
{
Console.WriteLine("文字列です");
}

型判定では、できるだけ文字列比較ではなく、typeofisを使うようにしましょう。

4. GetType()とtypeofの違い

4-1. GetType()はインスタンスから実行時の型を取得する

GetType()は、インスタンスから実行時の型を取得します。

C#
string text = "Hello";

Type type = text.GetType();

Console.WriteLine(type);

実行結果は次のようになります。

C#
System.String

GetType()を使うには、実際のオブジェクトが必要です。

C#
string text = "Hello";
text.GetType();

つまり、GetType()は「この変数に実際に入っているオブジェクトは何型か」を調べるためのものです。

4-2. typeofは型そのものをコンパイル時に取得する

typeofは、型そのものを取得するための演算子です。

C#
Type type = typeof(string);

Console.WriteLine(type);

実行結果は次のようになります。

C#
System.String

typeofはインスタンスを必要としません。

C#
Type type1 = typeof(string);
Type type2 = typeof(int);
Type type3 = typeof(DateTime);

このように、型名を直接指定してTypeオブジェクトを取得できます。

GetType()が「実際のオブジェクトから型を取得する」のに対して、typeofは「型そのものをコード上で指定して取得する」という違いがあります。

4-3. GetType()とtypeofの使い分け

GetType()typeofは、目的によって使い分けます。

実際に入っている値の型を知りたい場合はGetType()を使います。

C#
object value = "Hello";

Console.WriteLine(value.GetType());

特定の型を表すTypeオブジェクトが欲しい場合はtypeofを使います。

C#
Type stringType = typeof(string);

型を比較したい場合は、両方を組み合わせます。

C#
object value = "Hello";

if (value.GetType() == typeof(string))
{
Console.WriteLine("string型です");
}

まとめると、次のようになります。

機能使い方意味
GetType()value.GetType()インスタンスの実行時の型を取得する
typeoftypeof(string)指定した型そのものを取得する
GetType() == typeof()value.GetType() == typeof(string)実行時の型が指定した型と完全一致するか判定する

4-4. GetType() == typeof()の実用例

GetType() == typeof()は、値の型が完全に一致しているかを確認したいときに使えます。

C#
object input = 123;

if (input.GetType() == typeof(int))
{
int number = (int)input;
Console.WriteLine(number * 2);
}

実行結果は次のようになります。

C#
246

ログ出力やデバッグ時にも使えます。

C#
object data = DateTime.Now;

if (data.GetType() == typeof(DateTime))
{
Console.WriteLine("日付データです");
}

ただし、継承関係がある場合には注意が必要です。

C#
class Animal
{
}

class Dog : Animal
{
}

Animal animal = new Dog();

Console.WriteLine(animal.GetType() == typeof(Animal));
Console.WriteLine(animal.GetType() == typeof(Dog));

実行結果は次のようになります。

C#
False
True

変数の宣言はAnimal型ですが、実際のインスタンスはDog型です。そのため、GetType()Dogを返します。

4-5. 初心者が混同しやすいポイント

初心者が混同しやすいのは、次の2つです。

C#
value.GetType()
C#
typeof(string)

GetType()は変数やオブジェクトに対して使います。

C#
string text = "Hello";
Type type = text.GetType();

typeofは型名に対して使います。

C#
Type type = typeof(string);

次のような書き方はできません。

C#
// エラー
string.GetType();

stringは型名であり、インスタンスではないためです。

また、次のような書き方もできません。

C#
// エラー
typeof(text);

typeofには変数名ではなく、型名を指定します。

正しくは次のように使い分けます。

C#
string text = "Hello";

Console.WriteLine(text.GetType());
Console.WriteLine(typeof(string));

どちらもSystem.Stringを表しますが、取得の仕方が違います。

5. GetType()とisの違い

5-1. isは指定した型として扱えるかを判定する

isは、オブジェクトが指定した型として扱えるかどうかを判定します。

C#
object value = "Hello";

if (value is string)
{
Console.WriteLine("stringとして扱えます");
}

実行結果は次のようになります。

C#
stringとして扱えます

isは、型判定だけでなく、パターンマッチングと組み合わせて使うこともできます。

C#
object value = "Hello";

if (value is string text)
{
Console.WriteLine(text.Length);
}

この書き方では、valuestringとして扱える場合に、textという変数に代入されます。

5-2. GetType()は完全一致の型判定になる

GetType()を使った型判定は、実際の型が指定した型と完全に一致するかを判定します。

C#
object value = "Hello";

if (value.GetType() == typeof(string))
{
Console.WriteLine("実際の型はstringです");
}

この場合、実際の型がstringなので条件はtrueになります。

ただし、継承関係がある場合、GetType()は基底クラスではなく実際の派生クラスを返します。そのため、基底クラスとの比較ではfalseになることがあります。

C#
class Animal
{
}

class Dog : Animal
{
}

Animal animal = new Dog();

Console.WriteLine(animal.GetType() == typeof(Animal));

実行結果は次のようになります。

C#
False

animalという変数の宣言上の型はAnimalですが、実際のオブジェクトはDogです。そのため、GetType()の結果はDogになります。

5-3. 継承関係がある場合のGetType()とisの違い

継承関係がある場合、GetType()isの違いがはっきりします。

C#
class Animal
{
}

class Dog : Animal
{
}

Animal animal = new Dog();

Console.WriteLine(animal.GetType() == typeof(Animal));
Console.WriteLine(animal.GetType() == typeof(Dog));

Console.WriteLine(animal is Animal);
Console.WriteLine(animal is Dog);

実行結果は次のようになります。

C#
False
True
True
True

GetType()は実際の型が完全に一致するかを見ます。

C#
animal.GetType() == typeof(Animal)

これは、実際の型がDogなのでfalseです。

一方で、isは「その型として扱えるか」を見ます。

C#
animal is Animal

DogAnimalを継承しているため、Animalとして扱えます。そのためtrueになります。

この違いは非常に重要です。

完全に同じ型かを調べたいならGetType()、基底クラスや派生クラスの関係も含めて判定したいならisを使います。

5-4. インターフェース判定ではisが向いている理由

インターフェースを実装しているかどうかを判定する場合は、GetType()よりもisが向いています。

C#
interface IPrintable
{
void Print();
}

class Report : IPrintable
{
public void Print()
{
Console.WriteLine("印刷します");
}
}

object obj = new Report();

if (obj is IPrintable printable)
{
printable.Print();
}

実行結果は次のようになります。

C#
印刷します

GetType()でインターフェースを判定しようとしても、次のような比較は期待どおりになりません。

C#
Console.WriteLine(obj.GetType() == typeof(IPrintable));

実行結果は次のようになります。

C#
False

実際の型はReportであり、IPrintableそのものではないからです。

インターフェースを実装しているかどうかを確認したい場合は、次のようにisを使うのが自然です。

C#
if (obj is IPrintable)
{
Console.WriteLine("IPrintableを実装しています");
}

5-5. 型判定でGetType()とisを使い分ける基準

GetType()isの使い分けは、次のように考えるとわかりやすいです。

完全に同じ型かを判定したい場合はGetType()を使います。

C#
if (value.GetType() == typeof(string))
{
Console.WriteLine("実際の型はstringです");
}

指定した型として扱えるかを判定したい場合はisを使います。

C#
if (value is string text)
{
Console.WriteLine(text);
}

継承やインターフェースを考慮したい場合もisが向いています。

C#
if (animal is Animal)
{
Console.WriteLine("Animalとして扱えます");
}

初心者が型判定を書く場合は、まずisを検討するとよいです。GetType()は、実際の型が完全一致しているかどうかを厳密に確認したい場面で使いましょう。

6. GetType()を使うときの注意点

6-1. nullに対してGetType()を呼ぶと例外になる

GetType()を使うときに最も注意したいのが、nullです。

C#
string text = null;

Console.WriteLine(text.GetType());

このコードを実行すると、NullReferenceExceptionが発生します。

GetType()はインスタンスに対して呼び出すメソッドです。nullはオブジェクトが存在しない状態なので、GetType()を呼び出せません。

安全に使うには、事前にnullチェックをします。

C#
string text = null;

if (text != null)
{
Console.WriteLine(text.GetType());
}
else
{
Console.WriteLine("textはnullです");
}

また、null条件演算子を使うこともできます。

C#
string text = null;

Console.WriteLine(text?.GetType());

この場合、textnullならGetType()は呼ばれず、結果もnullになります。

型判定をする場合は、次のように書くと安全です。

C#
object value = null;

if (value != null && value.GetType() == typeof(string))
{
Console.WriteLine("string型です");
}

ただし、isを使えばnullの場合も安全に判定できます。

C#
object value = null;

if (value is string)
{
Console.WriteLine("string型です");
}
else
{
Console.WriteLine("string型ではありません");
}

6-2. 継承クラスでは基底クラスではなく実際の型が返る

GetType()は、変数の宣言上の型ではなく、実際のインスタンスの型を返します。

C#
class Animal
{
}

class Dog : Animal
{
}

Animal animal = new Dog();

Console.WriteLine(animal.GetType());

実行結果は次のようになります。

C#
Dog

変数animalの型はAnimalですが、実際に作成しているインスタンスはDogです。そのため、GetType()Dogを返します。

この性質は便利ですが、基底クラスかどうかを判定したい場合には注意が必要です。

C#
if (animal.GetType() == typeof(Animal))
{
Console.WriteLine("Animalです");
}

この条件はfalseになります。

基底クラスとして扱えるかどうかを判定したい場合は、isを使います。

C#
if (animal is Animal)
{
Console.WriteLine("Animalとして扱えます");
}

6-3. Nullable型でGetType()を使うときの注意点

Nullable<T>、つまりint?のようなnull許容値型でGetType()を使う場合は注意が必要です。

C#
int? number = 10;

Console.WriteLine(number.GetType());

実行結果は次のようになります。

C#
System.Int32

int?だからSystem.Nullable<System.Int32>が返ると思うかもしれませんが、値が入っている場合、GetType()の結果は中身の型であるSystem.Int32になります。

一方、値がnullの場合は注意が必要です。

C#
int? number = null;

// Console.WriteLine(number.GetType());

この場合、GetType()を呼ぼうとすると問題になります。Nullable<T>の値がない状態では、実際の値が存在しないためです。

Nullable<T>かどうかを型として確認したい場合は、typeofを使います。

C#
Console.WriteLine(typeof(int?));
Console.WriteLine(typeof(Nullable<int>));

どちらもNullable<int>を表します。

値が入っているかどうかは、HasValueで確認できます。

C#
int? number = 10;

if (number.HasValue)
{
Console.WriteLine(number.Value.GetType());
}
else
{
Console.WriteLine("値はnullです");
}

Nullable型では、GetType()で「null許容型そのもの」を確認するのではなく、値の有無やtypeofとの違いを意識する必要があります。

6-4. ジェネリック型でGetType()を使うときの注意点

ジェネリック型でもGetType()は使えます。

C#
void ShowType<T>(T value)
{
Console.WriteLine(value.GetType());
}

次のように呼び出します。

C#
ShowType("Hello");
ShowType(100);

実行結果は次のようになります。

C#
System.String
System.Int32

ただし、valuenullになる可能性がある場合は注意が必要です。

C#
void ShowType<T>(T value)
{
if (value != null)
{
Console.WriteLine(value.GetType());
}
else
{
Console.WriteLine("valueはnullです");
}
}

また、ジェネリックの型引数そのものを取得したい場合は、typeof(T)を使います。

C#
void ShowType<T>(T value)
{
Console.WriteLine(typeof(T));
}

GetType()は実際の値の型、typeof(T)はジェネリック型引数として指定された型を表します。

違いを確認してみましょう。

C#
void ShowType<T>(T value)
{
Console.WriteLine($"typeof(T): {typeof(T)}");
Console.WriteLine($"value.GetType(): {value.GetType()}");
}

object text = "Hello";
ShowType<object>(text);

実行結果は次のようになります。

C#
typeof(T): System.Object
value.GetType(): System.String

Tobjectですが、実際の値はstringです。そのため、typeof(T)GetType()の結果が異なります。

6-5. 型判定に依存しすぎる設計は避ける

GetType()は便利ですが、型判定に依存しすぎる設計は避けるべきです。

たとえば、次のようなコードがあるとします。

C#
if (animal.GetType() == typeof(Dog))
{
Console.WriteLine("犬の処理");
}
else if (animal.GetType() == typeof(Cat))
{
Console.WriteLine("猫の処理");
}

このようなコードは、クラスが増えるたびに条件分岐を追加する必要があります。

オブジェクト指向では、型ごとの処理はクラス自身に持たせるほうが自然です。

C#
class Animal
{
public virtual void Speak()
{
Console.WriteLine("動物の鳴き声");
}
}

class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("ワン");
}
}

class Cat : Animal
{
public override void Speak()
{
Console.WriteLine("ニャー");
}
}

使う側は型判定をせずに呼び出せます。

C#
Animal animal = new Dog();
animal.Speak();

実行結果は次のようになります。

C#
ワン

型判定が必要な場面もありますが、頻繁にGetType()で分岐している場合は、設計を見直すサインかもしれません。

7. GetType()の実践サンプル

7-1. 変数の型を確認するサンプル

まずは、複数の変数の型を確認するサンプルです。

C#
string name = "Taro";
int age = 25;
double height = 170.5;
bool isActive = true;
DateTime createdAt = DateTime.Now;

Console.WriteLine(name.GetType());
Console.WriteLine(age.GetType());
Console.WriteLine(height.GetType());
Console.WriteLine(isActive.GetType());
Console.WriteLine(createdAt.GetType());

実行結果の例は次のとおりです。

C#
System.String
System.Int32
System.Double
System.Boolean
System.DateTime

型名だけを表示したい場合は、Nameを使います。

C#
Console.WriteLine(name.GetType().Name);
Console.WriteLine(age.GetType().Name);
Console.WriteLine(height.GetType().Name);

実行結果は次のようになります。

C#
String
Int32
Double

7-2. Listや配列の型を取得するサンプル

配列に対してもGetType()を使えます。

C#
int[] numbers = { 1, 2, 3 };

Console.WriteLine(numbers.GetType());
Console.WriteLine(numbers.GetType().Name);

実行結果の例は次のようになります。

C#
System.Int32[]
Int32[]

List<T>の場合は次のようになります。

C#
List<string> names = new List<string> { "Taro", "Hanako" };

Console.WriteLine(names.GetType());
Console.WriteLine(names.GetType().Name);
Console.WriteLine(names.GetType().FullName);

実行結果の例は次のようになります。

C#
System.Collections.Generic.List`1[System.String]
List`1
System.Collections.Generic.List`1[[System.String, System.Private.CoreLib, Version=...]]

ジェネリック型では、表示が少し複雑になることがあります。

要素の型を取得したい場合は、次のように確認できます。

C#
Type listType = names.GetType();
Type elementType = listType.GetGenericArguments()[0];

Console.WriteLine(elementType);

実行結果は次のようになります。

C#
System.String

配列の要素型を取得したい場合は、GetElementType()を使います。

C#
int[] numbers = { 1, 2, 3 };

Type elementType = numbers.GetType().GetElementType();

Console.WriteLine(elementType);

実行結果は次のようになります。

C#
System.Int32

7-3. 自作クラスの型を取得するサンプル

自作クラスでもGetType()を使って型情報を取得できます。

C#
class User
{
public string Name { get; set; }
public int Age { get; set; }
}

class Program
{
static void Main()
{
User user = new User
{
Name = "Taro",
Age = 25
};

Type type = user.GetType();

Console.WriteLine(type.Name);
Console.WriteLine(type.FullName);
}
}

実行結果の例は次のようになります。

C#
User
User

名前空間を付けると、FullNameに名前空間が含まれます。

C#
namespace MyApp.Models
{
class User
{
public string Name { get; set; }
public int Age { get; set; }
}
}
C#
var user = new MyApp.Models.User();

Console.WriteLine(user.GetType().Name);
Console.WriteLine(user.GetType().FullName);

実行結果は次のようになります。

C#
User
MyApp.Models.User

7-4. 継承クラスでGetType()の結果を確認するサンプル

継承関係がある場合のGetType()の結果を確認してみましょう。

C#
class Animal
{
}

class Dog : Animal
{
}

class Cat : Animal
{
}

class Program
{
static void Main()
{
Animal animal1 = new Dog();
Animal animal2 = new Cat();

Console.WriteLine(animal1.GetType());
Console.WriteLine(animal2.GetType());
}
}

実行結果は次のようになります。

C#
Dog
Cat

変数の宣言上はどちらもAnimal型ですが、実際に生成された型はDogCatです。

型判定をしてみます。

C#
Animal animal = new Dog();

Console.WriteLine(animal.GetType() == typeof(Animal));
Console.WriteLine(animal.GetType() == typeof(Dog));
Console.WriteLine(animal is Animal);
Console.WriteLine(animal is Dog);

実行結果は次のとおりです。

C#
False
True
True
True

この例から、GetType()は実際の型の完全一致を確認し、isは指定した型として扱えるかどうかを確認することがわかります。

7-5. デバッグ時に型情報を出力するサンプル

GetType()は、デバッグ時のログ出力にも便利です。

C#
void PrintValue(object value)
{
if (value == null)
{
Console.WriteLine("値: null, 型: なし");
return;
}

Console.WriteLine($"値: {value}, 型: {value.GetType().FullName}");
}

呼び出し例です。

C#
PrintValue("Hello");
PrintValue(123);
PrintValue(DateTime.Now);
PrintValue(null);

実行結果の例は次のようになります。

C#
: Hello, : System.String
: 123, : System.Int32
: 2026/06/07 10:00:00, : System.DateTime
: null, : なし

このように、object型で受け取った値の中身を確認したいときにGetType()は役立ちます。

特に、外部APIから取得したデータや、汎用的なメソッドで受け取った値を確認する場合に便利です。

8. GetType()とリフレクションの関係

8-1. GetType()で取得したTypeからプロパティ情報を取得する

GetType()で取得したTypeを使うと、リフレクションによってプロパティ情報を取得できます。

リフレクションとは、プログラムの実行中に型の情報を調べたり、プロパティやメソッドにアクセスしたりする仕組みです。

次の例を見てみましょう。

C#
class User
{
public string Name { get; set; }
public int Age { get; set; }
}

class Program
{
static void Main()
{
User user = new User
{
Name = "Taro",
Age = 25
};

Type type = user.GetType();

foreach (var property in type.GetProperties())
{
Console.WriteLine(property.Name);
}
}
}

実行結果は次のようになります。

C#
Name
Age

GetProperties()を使うと、その型が持つpublicプロパティの情報を取得できます。

プロパティ名だけでなく、値を取得することもできます。

C#
foreach (var property in type.GetProperties())
{
object value = property.GetValue(user);
Console.WriteLine($"{property.Name}: {value}");
}

実行結果は次のようになります。

C#
Name: Taro
Age: 25

8-2. メソッド情報を取得する

Typeからメソッド情報を取得するには、GetMethods()を使います。

C#
class User
{
public string Name { get; set; }

public void SayHello()
{
Console.WriteLine("Hello");
}
}

class Program
{
static void Main()
{
User user = new User();

Type type = user.GetType();

foreach (var method in type.GetMethods())
{
Console.WriteLine(method.Name);
}
}
}

実行結果には、SayHelloのほか、ToStringEqualsなど、継承元のメソッドも含まれます。

C#
get_Name
set_Name
SayHello
GetType
ToString
Equals
GetHashCode

プロパティは内部的にget_Nameset_Nameのようなメソッドとして扱われるため、これらも表示されます。

特定のメソッドを取得したい場合は、GetMethod()を使います。

C#
var method = type.GetMethod("SayHello");

Console.WriteLine(method.Name);

さらに、リフレクションを使えばメソッドを実行することもできます。

C#
method.Invoke(user, null);

実行結果は次のようになります。

C#
Hello

8-3. フィールド情報を取得する

フィールド情報を取得するには、GetFields()を使います。

C#
class User
{
public string Name;
public int Age;
}

class Program
{
static void Main()
{
User user = new User
{
Name = "Taro",
Age = 25
};

Type type = user.GetType();

foreach (var field in type.GetFields())
{
Console.WriteLine(field.Name);
}
}
}

実行結果は次のようになります。

C#
Name
Age

フィールドの値を取得することもできます。

C#
foreach (var field in type.GetFields())
{
object value = field.GetValue(user);
Console.WriteLine($"{field.Name}: {value}");
}

実行結果は次のようになります。

C#
Name: Taro
Age: 25

ただし、C#ではフィールドを直接公開するよりも、プロパティを使う設計が一般的です。

C#
public string Name { get; set; }

そのため、実務ではGetFields()よりもGetProperties()を使う場面のほうが多いです。

8-4. リフレクションを使うメリットと注意点

リフレクションを使うと、実行時に型の情報を柔軟に扱えます。

たとえば、次のような場面で使われます。

JSONのシリアライズやデシリアライズ。

オブジェクトのプロパティ一覧を自動的に取得する処理。

DIコンテナやフレームワーク内部の処理。

テストツールや開発支援ツール。

汎用的なマッピング処理。

一方で、リフレクションには注意点もあります。

通常のプロパティアクセスよりコードが複雑になりやすいです。

C#
user.Name

と書けば済むところを、リフレクションでは次のように書く必要があります。

C#
var property = user.GetType().GetProperty("Name");
var value = property.GetValue(user);

また、文字列でプロパティ名やメソッド名を指定することが多いため、タイプミスに気づきにくいです。

C#
var property = user.GetType().GetProperty("Nmae");

このような間違いはコンパイルエラーにならず、実行時に問題が発生します。

さらに、リフレクションは通常のコードよりもパフォーマンス面で不利になることがあります。大量に繰り返し実行する処理では注意が必要です。

8-5. 初心者がまず覚えるべき範囲

初心者が最初に覚えるべき範囲は、次の3つです。

まず、GetType()で実行時の型を取得できることです。

C#
Console.WriteLine(value.GetType());

次に、NameFullNameで型名を取得できることです。

C#
Console.WriteLine(value.GetType().Name);
Console.WriteLine(value.GetType().FullName);

そして、型判定ではtypeofisとの違いを理解することです。

C#
if (value.GetType() == typeof(string))
{
Console.WriteLine("実際の型はstringです");
}

if (value is string text)
{
Console.WriteLine("stringとして扱えます");
}

リフレクションについては、最初から深く覚える必要はありません。

まずは、GetType()で取得したTypeから、プロパティやメソッドの情報を取得できるというイメージを持っておけば十分です。

9. GetType()に関するよくある疑問

9-1. GetType()とtypeofはどちらを使えばよい?

実際のオブジェクトの型を知りたい場合はGetType()を使います。

C#
object value = "Hello";

Console.WriteLine(value.GetType());

型そのものを指定してTypeを取得したい場合はtypeofを使います。

C#
Console.WriteLine(typeof(string));

型判定では、両方を組み合わせることがあります。

C#
if (value.GetType() == typeof(string))
{
Console.WriteLine("string型です");
}

ただし、型として扱えるかを判定したいだけなら、isのほうが便利なことも多いです。

C#
if (value is string text)
{
Console.WriteLine(text);
}

使い分けの目安は次のとおりです。

やりたいこと使うもの
実際の型を取得したいGetType()
型そのものを取得したいtypeof
完全一致で型判定したいGetType() == typeof()
指定した型として扱えるか判定したいis

9-2. GetType()でクラス名だけ取得できる?

できます。

クラス名だけを取得したい場合は、GetType().Nameを使います。

C#
User user = new User();

Console.WriteLine(user.GetType().Name);

実行結果は次のようになります。

C#
User

名前空間を含む型名を取得したい場合は、FullNameを使います。

C#
Console.WriteLine(user.GetType().FullName);

実行結果の例は次のとおりです。

C#
MyApp.Models.User

表示用にはName、正確な型の識別にはFullNameを使うとよいでしょう。

9-3. GetType()でインターフェース実装を判定できる?

GetType()だけでインターフェース実装を直接判定するのは、あまりおすすめできません。

たとえば、次のコードを見てください。

C#
interface ILogger
{
void Log(string message);
}

class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}

object logger = new ConsoleLogger();

Console.WriteLine(logger.GetType() == typeof(ILogger));

実行結果は次のようになります。

C#
False

実際の型はConsoleLoggerであり、ILoggerそのものではないからです。

インターフェースを実装しているかどうかを判定したい場合は、isを使いましょう。

C#
if (logger is ILogger)
{
Console.WriteLine("ILoggerを実装しています");
}

実行結果は次のようになります。

C#
ILoggerを実装しています

リフレクションで判定する方法もあります。

C#
bool result = typeof(ILogger).IsAssignableFrom(logger.GetType());

Console.WriteLine(result);

実行結果は次のようになります。

C#
True

ただし、通常のコードではisを使うほうがシンプルです。

9-4. GetType()でnull判定はできる?

GetType()null判定はできません。

なぜなら、nullに対してGetType()を呼び出すと例外になるからです。

C#
object value = null;

// 例外になる
Console.WriteLine(value.GetType());

nullかどうかを確認したい場合は、先にnullチェックをします。

C#
object value = null;

if (value == null)
{
Console.WriteLine("valueはnullです");
}
else
{
Console.WriteLine(value.GetType());
}

型判定と組み合わせる場合は、次のように書けます。

C#
object value = null;

if (value != null && value.GetType() == typeof(string))
{
Console.WriteLine("string型です");
}

または、isを使う方法もあります。

C#
object value = null;

if (value is string text)
{
Console.WriteLine(text);
}
else
{
Console.WriteLine("string型ではない、またはnullです");
}

isnullに対しても安全に使えるため、型判定では便利です。

9-5. GetType()はパフォーマンスに影響する?

GetType()を通常の範囲で使うだけなら、過度に心配する必要はありません。

たとえば、デバッグ出力や少数の型判定で使う程度であれば、パフォーマンス上の問題になることはほとんどありません。

C#
Console.WriteLine(value.GetType());

ただし、非常に大量のデータに対して何度もGetType()を呼び出したり、リフレクションでプロパティやメソッドを繰り返し取得したりする場合は注意が必要です。

C#
foreach (var item in items)
{
var properties = item.GetType().GetProperties();

foreach (var property in properties)
{
Console.WriteLine(property.Name);
}
}

このような処理では、型情報を毎回取得するのではなく、必要に応じてキャッシュすることを検討します。

C#
Type type = typeof(User);
var properties = type.GetProperties();

foreach (var user in users)
{
foreach (var property in properties)
{
Console.WriteLine(property.GetValue(user));
}
}

通常の型判定では大きな問題になりにくいですが、リフレクションを大量に使う処理では設計や実装を工夫しましょう。

まとめ

C#のGetType()は、オブジェクトの実行時の型を取得するためのメソッドです。stringint、自作クラス、配列、Listなど、さまざまなオブジェクトに対して使えます。

基本的な使い方は次のとおりです。

C#
object value = "Hello";

Console.WriteLine(value.GetType());
Console.WriteLine(value.GetType().Name);
Console.WriteLine(value.GetType().FullName);

GetType()は、実際に入っているオブジェクトの型を取得します。一方、typeofは型そのものをコード上で指定して取得します。

C#
value.GetType();
typeof(string);

型が完全に一致するかを判定したい場合は、次のように書きます。

C#
if (value.GetType() == typeof(string))
{
Console.WriteLine("string型です");
}

ただし、継承関係やインターフェースを考慮したい場合は、GetType()よりもisが向いています。

C#
if (value is string text)
{
Console.WriteLine(text);
}

GetType()を使うときは、nullに注意が必要です。nullに対してGetType()を呼び出すとNullReferenceExceptionが発生します。

C#
if (value != null)
{
Console.WriteLine(value.GetType());
}

また、Nullable<T>やジェネリック型では、GetType()typeofの違いを意識することが大切です。

GetType()はデバッグや型確認、リフレクションの入り口として便利なメソッドです。ただし、型判定に依存しすぎるとコードが複雑になりやすいため、必要に応じてis、パターンマッチング、ポリモーフィズムなども使い分けましょう。