【C#】実行時にオブジェクトが「値型」か「クラス」かなどの型分類を調べる方法

C#では、Type クラスのプロパティを参照することで、その型が「値型なのか参照型なのか」「配列なのか」「ジェネリック型なのか」といった分類を実行時に判定できます。

汎用的な処理を行うライブラリやデバッグ用メソッドを作成する際に、これらの情報は非常に有用です。

目次

Typeクラスの主要な判定プロパティ

以下は、型の種類を判別するためによく使用される System.Type クラスのプロパティ一覧です。

プロパティ名意味例 (true になるもの)
IsValueType値型(構造体や列挙体)であるかint, double, DateTime, struct
IsEnum列挙型(Enum)であるかDayOfWeek, System.IO.FileMode
IsArray配列であるかint[], string[,]
IsClassクラス(参照型)であるか
※文字列やデリゲート、配列も含まれます
string, List<T>, object, class
IsGenericTypeジェネリック型であるかList<T>, Dictionary<TKey, TValue>

型判定の実装サンプル

以下のコードは、様々な型のオブジェクトを CheckType メソッドに渡し、それぞれのプロパティが true / false のどちらを返すかを確認するサンプルです。

サンプルコード

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        // ヘッダー出力
        Console.WriteLine($"{"Type Name",-12} | Value | Enum  | Array | Class | Generic");
        Console.WriteLine(new string('-', 65));

        // 様々なデータ型で判定を実行
        CheckType(10.3);                 // double (値型)
        CheckType("Hello");              // string (クラス)
        CheckType(DayOfWeek.Saturday);   // Enum (値型かつ列挙型)
        CheckType(new int[4]);           // int[] (クラスかつ配列)
        CheckType(new List<int>());      // List<int> (クラスかつジェネリック)
    }

    /// <summary>
    /// オブジェクトの型情報を判定して表示する
    /// </summary>
    static void CheckType(object obj)
    {
        if (obj == null) return;

        Type type = obj.GetType();

        // 型名を表示
        Console.Write($"{type.Name,-12} | ");

        // 各種判定プロパティの結果を表示
        // 見やすくするために条件演算子で "Yes" / "No " に変換しても良いですが、
        // ここでは bool 値をそのまま表示します。
        Console.Write($"{type.IsValueType,-5} | ");
        Console.Write($"{type.IsEnum,-5} | ");
        Console.Write($"{type.IsArray,-5} | ");
        Console.Write($"{type.IsClass,-5} | ");
        Console.Write($"{type.IsGenericType,-5}");
        
        Console.WriteLine(); // 改行
    }
}

実行結果

Type Name    | Value | Enum  | Array | Class | Generic
-----------------------------------------------------------------
Double       | True  | False | False | False | False
String       | False | False | False | True  | False
DayOfWeek    | True  | True  | False | False | False
Int32[]      | False | False | True  | True  | False
List`1       | False | False | False | True  | True

解説と注意点

1. 値型とクラスの関係

  • IsValueType: intdoublestruct(構造体)などで true になります。
  • IsClass: class 定義された型だけでなく、配列 (System.Array 継承) や 文字列 (System.String)、デリゲート も参照型であるため true になります。
  • したがって、配列は IsArrayIsClass も両方 true になります。

2. IsPrimitive(プリミティブ型)

上記の表には含めませんでしたが、Type.IsPrimitive というプロパティもあります。

これは int, double, bool, byte などの「基本的な型」でのみ true になります。DateTime や decimal、および string はプリミティブではないため false になります。

3. Nullの扱い

サンプルコードの CheckType メソッドでは、引数 objnull の場合、GetType() を呼び出すと例外(NullReferenceException)が発生するため、冒頭でチェックを行うか、null安全な実装にする必要があります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次