本文へスキップ
BecomeCoder

C#オブジェクト指向コース · 第2章 型を表現する · レッスン19

属性(Attribute)とリフレクション

ブラウザで完結

導入

[Obsolete][JsonPropertyName]のように、[...]でコードに付ける「メタ情報」が属性(Attribute)です。そして実行時に「この型にはどんなプロパティ・属性があるか」を調べる仕組みがリフレクションです。テストフレームワーク([Fact])やJSON変換、DIコンテナなど、実務のライブラリの多くがこの2つで動いています。

図解

flowchart LR
    C["コードに [Author("Taro")] を付ける"] --> META["型にメタ情報が埋め込まれる"]
    META -->|リフレクションで読む| RUN["実行時に属性やプロパティを取得"]
    RUN --> USE["ライブラリが自動処理<br/>(テスト実行・JSON変換など)"]

サンプル

// typeof / GetType: 実行時に「型そのもの」を得る
Console.WriteLine("hello".GetType().Name);   // String
Console.WriteLine(typeof(int).Name);          // Int32

// 属性を読む: [Author("Taro")] のメタ情報を実行時に取り出す
var attr = (AuthorAttribute?)Attribute.GetCustomAttribute(
    typeof(Report), typeof(AuthorAttribute));
Console.WriteLine(attr?.Name);   // Taro

// リフレクションでプロパティ名を列挙する
foreach (var prop in typeof(Report).GetProperties())
    Console.WriteLine(prop.Name);   // Title

// --- 型と属性の定義 ---
[Author("Taro")]
class Report
{
    public string Title { get; set; } = "";
}

// 属性は Attribute を継承して作る(名前の末尾 Attribute は付け方で省略できる)
class AuthorAttribute : Attribute
{
    public string Name { get; }
    public AuthorAttribute(string name) => Name = name;
}
  • 属性[名前(...)]でコードに付けるメタ情報。自作するにはAttribute継承する
  • リフレクションtypeof/GetTypeで型情報を取り、GetProperties/GetCustomAttributeで中身を調べる
  • 使うときは[Author("Taro")]のように、クラス名末尾のAttributeを省略できる
  • xUnitの[Fact]、JSONの[JsonPropertyName]など、既に使ってきた属性の仕組みがこれ

演習

double x = 3.14;

// TODO: 変数 x の型名を出力してください(Double)
___
  • 期待される出力: Double
ヒント1を見る

x.GetType()で型を取り、.Nameで名前が得られます

ヒント2を見る

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

まとめ

  • 属性は[...]で付けるメタ情報、リフレクションは実行時に型情報を読む仕組み
  • typeof/GetTypeGetProperties/GetCustomAttributeで中身を調べる
  • テスト・JSON・DIなど多くのライブラリがこの土台で動いている

次回: プログラムのメモリの使われ方とガベージコレクションです。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。