bucket-sort logo bucket-sort

プログラミングとインフラエンジニアリングの覚え書き

  • Posts
  • About
  • Contact
  1. Home
  2. All Posts
  3. [C#] 型メタデータとリフレクションの基礎を理解する

[C#] 型メタデータとリフレクションの基礎を理解する

Jul 5, 2026 C# , .NET bucket-sort

今回から数回に分けて、型メタデータ、リフレクション、属性、遅延バインディング、dynamic、そしてプラグイン構造を扱います。

これらは単なる文法知識ではありません。
実行時に型を調べる、外部 DLL を読み込む、属性で機能を発見する、プラグインを追加する、といった 拡張性の高いアプリケーション を作るための土台になります。

まずこの記事では、型メタデータと System.Type の基本を見ていきます。

型メタデータが必要な理由

.NET のアセンブリには、実行コードだけでなく、型に関する情報が含まれています。
たとえば、次のような情報です。

  • 型の名前
  • 名前空間
  • 基底クラス
  • 実装しているインターフェイス
  • フィールド
  • プロパティ
  • メソッド
  • コンストラクター
  • 属性
  • 定義元アセンブリ

このような情報を 型メタデータ と呼びます。

型メタデータがあることで、実行時に「このオブジェクトは何者か」「どんなメソッドを持つか」「どの属性が付いているか」を調べられます。
この仕組みを利用するのがリフレクションです。

サンプル用の型

この記事では、次のような簡単な型を使います。

namespace ReflectionSamples;

public enum EngineState
{
    Stopped,
    Running,
    Broken
}

public class Car
{
    public string Name { get; set; }
    public int CurrentSpeed { get; private set; }
    public EngineState State { get; private set; }

    public Car(string name)
    {
        Name = name;
        State = EngineState.Stopped;
    }

    public void Start()
    {
        State = EngineState.Running;
    }

    public void Accelerate(int delta)
    {
        CurrentSpeed += delta;
    }
}

このような普通の型でも、ビルド後のアセンブリには型名、プロパティ、メソッド、列挙値などの情報が保存されています。

オブジェクトから型情報を取得する

実行中のオブジェクトから型情報を取得するには、GetType() を使います。

using ReflectionSamples;

Car car = new Car("Mini");

Type type = car.GetType();

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

GetType() は、実際のオブジェクトの型を返します。
変数の宣言型ではなく、実体の型を調べたいときに便利です。

object value = new Car("Mini");

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

この場合、変数の型は object ですが、実体は Car なので Car の型情報が得られます。

コンパイル時に型情報を取得する

型名がコード上で分かっている場合は、typeof を使います。

using ReflectionSamples;

Type carType = typeof(Car);
Type enumType = typeof(EngineState);

Console.WriteLine(carType.FullName);
Console.WriteLine(enumType.FullName);

GetType() はオブジェクトから型を取得します。
typeof は型そのものから型情報を取得します。

Car car = new Car("Mini");

Type a = car.GetType();
Type b = typeof(Car);

Console.WriteLine(a == b);

この例では、どちらも同じ型情報を指すため True になります。

文字列から型情報を取得する

型名を文字列として持っている場合は、Type.GetType() を使えます。

Type? type = Type.GetType("System.String");

if (type != null)
{
    Console.WriteLine(type.FullName);
}

自作型の場合は、アセンブリ名まで必要になることがあります。

Type? type = Type.GetType(
    "ReflectionSamples.Car, MyApp");

Console.WriteLine(type?.FullName ?? "型が見つかりません。");

文字列から型を探す処理は、設定ファイルで型名を指定したい場合や、プラグイン機構を作る場合に使われます。
ただし、文字列はタイプミスに弱いため、可能な場所では typeof や共通インターフェイスを使う方が安全です。

定義元アセンブリを調べる

型情報から、その型がどのアセンブリに定義されているかを調べられます。

using System.Reflection;
using ReflectionSamples;

Type type = typeof(Car);
Assembly assembly = type.Assembly;

Console.WriteLine(assembly.FullName);
Console.WriteLine(assembly.Location);

プラグインやライブラリを扱うとき、「この型はどの DLL から来たのか」を調べる場面があります。
type.Assembly はその入口になります。

参照しているアセンブリを調べる

アセンブリが参照している別のアセンブリも取得できます。

using System.Reflection;
using ReflectionSamples;

Assembly assembly = typeof(Car).Assembly;

foreach (AssemblyName name in assembly.GetReferencedAssemblies())
{
    Console.WriteLine(name.FullName);
}

依存関係の把握、診断ログ、プラグインの互換性チェックなどで役立ちます。

文字列リテラルを調べるという考え方

アセンブリには、コード内で使われる文字列リテラルも含まれます。
通常の C# コードから「すべての文字列リテラル」を簡単に列挙する API はありませんが、逆コンパイルツールやメタデータ閲覧ツールを使うと、アセンブリ内の情報を確認できます。

この事実は、セキュリティ面でも重要です。
API キー、パスワード、接続文字列などをコードへ直接書くと、ビルド後のファイルから読み取られる可能性があります。

// 避けたい例
string apiKey = "hard-coded-secret";

秘密情報は、環境変数、ユーザーシークレット、クラウドの秘密情報管理サービスなどへ逃がすのが基本です。

型情報を見るための小さな関数

最後に、型情報の要約を表示する関数を作ってみます。

using System.Reflection;

static void PrintTypeSummary(Type type)
{
    Console.WriteLine($"型名: {type.FullName}");
    Console.WriteLine($"基底型: {type.BaseType?.FullName}");
    Console.WriteLine($"アセンブリ: {type.Assembly.GetName().Name}");
    Console.WriteLine($"public 型: {type.IsPublic}");
    Console.WriteLine($"抽象型: {type.IsAbstract}");
    Console.WriteLine($"ジェネリック型: {type.IsGenericType}");

    Console.WriteLine("メソッド:");
    foreach (MethodInfo method in type.GetMethods(
        BindingFlags.Public |
        BindingFlags.Instance |
        BindingFlags.Static |
        BindingFlags.DeclaredOnly))
    {
        Console.WriteLine($"  {method.Name}");
    }
}

使い方です。

PrintTypeSummary(typeof(string));
PrintTypeSummary(typeof(List<int>));

このように、リフレクションを使うと、型に関する情報を実行時に調べられます。

まとめ

型メタデータは、.NET アセンブリに含まれる型情報です。
System.Type を使うと、型名、メンバー、定義元アセンブリ、属性などを実行時に調べられます。

この仕組みは、DI コンテナー、テストフレームワーク、シリアライザー、プラグイン機構など、多くの拡張性の土台になっています。

次回は、メソッド、フィールド、プロパティ、インターフェイス、ジェネリック型などを詳しく調べる、実践的なメタデータビューアを作ります。

C# .NET リフレクション メタデータ System.Type Assembly
← [C#] NuGet パッケージとアプリケーション発行を理解する [C#] リフレクションで型の中身を調べる →

Related Posts

  • [C#] 属性でコードに意味を与える Jul 8, 2026
  • [C#] リフレクションで型の中身を調べる Jul 6, 2026
  • [C#] プラグインで拡張できるアプリケーションを設計する Jul 9, 2026
  • [C#] 外部アセンブリを読み込み実行時に型を呼び出す Jul 7, 2026

Table of Contents

  • 型メタデータが必要な理由
  • サンプル用の型
  • オブジェクトから型情報を取得する
  • コンパイル時に型情報を取得する
  • 文字列から型情報を取得する
  • 定義元アセンブリを調べる
  • 参照しているアセンブリを調べる
  • 文字列リテラルを調べるという考え方
  • 型情報を見るための小さな関数
  • まとめ

Recent Posts

  • [C#] プラグインで拡張できるアプリケーションを設計する Jul 9, 2026
  • [C#] 属性でコードに意味を与える Jul 8, 2026
  • [C#] 外部アセンブリを読み込み実行時に型を呼び出す Jul 7, 2026
  • [C#] リフレクションで型の中身を調べる Jul 6, 2026
  • [C#] 型メタデータとリフレクションの基礎を理解する Jul 5, 2026

Categories

  • C#120
  • .NET119
  • AWS27
  • Laravel16
  • Linux15
  • MySQL9
  • Apache8
  • PHP8
  • DynamoDB6
  • セキュリティ6
  • Nginx5
  • WordPress4
  • インフラ4
  • Hugo3
  • .NET Framework1
  • Aurora1
  • Diagnostics1
  • Filament1
  • Git1
  • SQS1

Tags

  • C#
  • .NET
  • AWS
  • Laravel
  • コレクション
  • PHP
  • セキュリティ
  • MySQL
  • Linux
  • パフォーマンス
  • Apache
  • System.Collections.Generic
  • デリゲート
  • Code Snippet
  • DynamoDB
  • LINQ
  • NoSQL
  • PHP-FPM
  • RDS
  • System.Collections
  • Windows
  • メモリ管理
  • リフレクション
  • DoS
  • Nginx
  • WordPress
  • メタデータ
  • ラムダ式
  • 監視
  • 設計
  • Amazon Linux 2023
  • Delegate
  • Docker
  • IDisposable
  • Ipset
  • Iptables
  • LINQ to Objects
  • OPCache
  • Pointer
  • Reflection
  • System.Collections.Specialized
  • Unsafe
  • Webサーバー
  • インターフェース
  • オブジェクト指向
  • クラス設計
  • デザインパターン
  • パターンマッチング
  • ポインター
  • 継承
Powered by Hugo & Explore Theme.