記事内にはプロモーションが含まれています

【C#】クラス名を取得する最新手法まとめ!nameof・GetTypeの使い分けからstatic・継承時の挙動まで

【C#】クラス名を取得する最新手法まとめ!nameof・GetTypeの使い分けからstatic・継承時の挙動まで C#

C#で開発を行っていると、例外処理のログ出力や、デバッグ用のメッセージ表示などで「現在のクラス名」や「実行中のメソッド名」を取得したい場面が頻繁に訪れます。

「クラス名を文字列で直接書くと、リファクタリングで名前を変えた時に修正が面倒……」
「継承先でメソッドを呼んだ時、親クラスの名前ではなく子クラスの名前を取りたい」
「static(静的)メソッドの中から自分自身のクラス名を知るには?」

このような悩みを抱えている開発者の方に向けて、C#でクラス名・メソッド名を取得するための最適な方法を網羅的に解説します。

パフォーマンスに優れた nameof 演算子から、実行時の型判定に欠かせない GetType、さらには最新の CallerMemberName 属性まで、状況に応じた使い分けをマスターしましょう。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はこじんまりとしたプログラミングスクールを運営
  • モットーは「利他の精神」

クラス名を取得する基本的な方法(nameof と GetType)

C#でクラス名を取得する方法はいくつかありますが、まずは最も一般的かつ重要な2つの手法、「nameof」と「GetType」を比較しながら見ていきましょう。

クラス名の取得においては、この2つの使い分けを理解することが、バグの少ないクリーンなコードを書くための第一歩となります。

1. 【推奨】コンパイル時に確定する nameof 演算子

C# 6.0以降、最も推奨されるのが nameof 演算子です。

これは引数に渡した型やメンバーの名前を「文字列」として返します。

using System;

public class SampleService
{
    public void OutputName()
    {
        // クラス名を文字列で取得
        string className = nameof(SampleService);
        Console.WriteLine($"クラス名: {className}");
    }
}

class Program
{
    static void Main()
    {
        var service = new SampleService();
        service.OutputName();
    }
}

このソースコードは、nameof(SampleService) を使って自分自身のクラス名を取得しています。

最大の利点は、コンパイル時に文字列として埋め込まれるため、実行時のパフォーマンス負荷が一切ないことです。

さらに、Visual Studioのリファクタリング機能でクラス名を変更した場合、nameof の中身も自動的に追従して修正されるため、修正漏れによるバグ(文字列のハードコーディングミス)を確実に防げます。

2. 実行時の型情報を取得する GetType().Name

インスタンスが存在する場合、Object.GetType() メソッドを使用して実行時の型情報を取得できます。

using System;

public class DataProcessor
{
    public void Process()
    {
        // 自身のインスタンスから型名を取得
        string typeName = this.GetType().Name;
        Console.WriteLine($"実行中の型名: {typeName}");
    }
}

このコードでは、this.GetType().Name を呼び出すことで、オブジェクト自身のクラス名を動的に取得しています。

nameof がコード上の識別子を固定して取得するのに対し、GetType は実行しているオブジェクトの実体(インスタンス)に基づいて名前を取得する点が異なります。

これは次に解説する「継承」が絡む場面で非常に重要になります。

特定の状況でクラス名を取得するテクニック(static・継承)

実務では、単純な取得だけでなく「staticメソッド内」や「継承関係がある場合」など、少し複雑な条件での取得が求められることがあります。

それぞれのケースで期待通りの名前を取得するための注意点を確認しましょう。

継承先(子クラス)の名前を取得する

親クラスに共通のログ出力メソッドを作り、子クラスで実行した際に「子クラスの名前」を出したい場合は、GetType が最適です。

using System;

public class BaseClass
{
    public void PrintCurrentClassName()
    {
        // this.GetType() は「実際に生成された型」を返す
        Console.WriteLine($"現在の実体クラス名: {this.GetType().Name}");
    }
}

public class ChildClass : BaseClass { }

class Program
{
    static void Main()
    {
        BaseClass obj = new ChildClass();
        obj.PrintCurrentClassName(); // 出力結果はどうなる?
    }
}

実行結果は ChildClass と表示されます。

ソース内で this.GetType() を使用すると、メソッドが定義されているのは BaseClass であっても、呼び出し元の実体(インスタンス)である ChildClass の情報が返されるからです。

逆に、ここで nameof(BaseClass) を使ってしまうと、どの継承先から呼んでも常に BaseClass と固定されてしまうため、用途に応じて使い分ける必要があります。

staticメソッド内でクラス名を取得する(typeof)

static(静的)メソッド内では this キーワードが使えないため、this.GetType() を書くことはできません。
この場合は typeof 演算子を使用します。

using System;

public static class AppLogger
{
    public static void Log()
    {
        // staticメソッド内では typeof(クラス名) を使う
        string className = typeof(AppLogger).Name;
        
        // または nameof を使う(推奨)
        string classNameSimple = nameof(AppLogger);

        Console.WriteLine($"Class: {classNameSimple}");
    }
}

このコードでは typeof(AppLogger).Name を使用していますが、クラス名がコンパイル時に分かっている static メソッドであれば、よりシンプルで高速な nameof(AppLogger) を使うのがベストプラクティスです。

typeof は主に、名前空間を含めたフルネーム(FullName)を取得したい場合や、ジェネリック型を扱う際に利用されます。

メソッド名と呼び出し元の情報を取得する方法

クラス名だけでなく、「どのメソッドが実行されているか」「どの行でエラーが起きたか」という情報もデバッグには不可欠です。

最新のC#では、リフレクションを使わずに軽量にこれらの情報を取得する仕組みが提供されています。

CallerMemberName属性による軽量な取得

ログ出力用メソッドなどで、呼び出し元のメソッド名を自動的に取得するには System.Runtime.CompilerServices.CallerMemberName 属性が非常に便利です。

using System;
using System.Runtime.CompilerServices; // 必須

public class Debugger
{
    public void Trace(string message, 
                     [CallerMemberName] string memberName = "")
    {
        // 呼び出し元のメソッド名が memberName に自動的に入る
        Console.WriteLine($"[{memberName}] Log: {message}");
    }

    public void ExecuteTask()
    {
        Trace("タスクを開始します");
    }
}

このコードを実行すると [ExecuteTask] Log: タスクを開始します と出力されます。

従来は MethodBase.GetCurrentMethod().Name というリフレクションを使った重い処理が必要でしたが、この属性を使えばコンパイル時に呼び出し元の名前が引数に差し込まれるため、非常に高速に動作します。

MethodBase.GetCurrentMethod() を使った取得

より動的に、現在のスタックフレームからメソッド情報を取得したい場合は System.Reflection を使用します。

using System;
using System.Reflection;

public class LegacyLogger
{
    public void LogCurrentMethod()
    {
        // 現在実行中のメソッド情報を取得
        MethodBase current = MethodBase.GetCurrentMethod();
        
        Console.WriteLine($"クラス: {current.DeclaringType.Name}");
        Console.WriteLine($"メソッド: {current.Name}");
    }
}

このソースは MethodBase.GetCurrentMethod() を経由して、現在地の情報を取得しています。

汎用的な共通部品で、「どこから呼ばれても自動で名前を記録したい」場合には便利ですが、リフレクションは実行時の負荷が高いため、頻繁に呼び出されるループ処理内などでの使用は避けるのが賢明です。

クラス名からクラス(型)を取得する方法

「文字列としての名前」を取得するのとは逆に、「文字列のクラス名から型情報(Type)を取得したい」というニーズもあります。

これを実現するには Type.GetType() メソッドを使用しますが、名前の指定方法に注意が必要です。

using System;

public class UserProfile { }

class Program
{
    static void Main()
    {
        // 名前空間を含めた完全修飾名(Full Name)が必要
        string targetName = "YourApp.Models.UserProfile";
        
        Type t = Type.GetType(targetName);

        if (t != null)
        {
            Console.WriteLine($"型を特定しました: {t.AssemblyQualifiedName}");
            // インスタンスの生成も可能
            var instance = Activator.CreateInstance(t);
        }
    }
}

この解説において重要なのは、Type.GetType に渡す文字列は、単なる「クラス名」ではなく「名前空間.クラス名」という完全修飾名でなければならないという点です。

外部の設定ファイル(JSONやXML)から動的に生成するクラスを切り替えたい場合などに重宝するテクニックとなります。

C# クラス名・識別子の命名規則

最後に、クラス名を取得して扱う上で意識しておきたい「C#の標準的な命名規則」についても触れておきます。

  • PascalCase(パスカルケース): クラス名、メソッド名、プロパティ名は、単語の先頭をすべて大文字にします(例: CustomerManager)。
  • 名詞の使用: クラス名は基本的に「名詞」にします。
  • 省略を避ける: Info ではなく InformationSvc ではなく Service と記述するのが、モダンなC#開発の推奨事項です。

これらの規則を守ることで、nameof 演算子などで取得した際の名前も一貫性が保たれ、可読性の高いシステムを構築できます。

C#のスキルを活かして年収を上げる方法

以上、C#でラジオボタンをグループ化する方法を中心に解説してきました。

なお、C#のスキルがある場合には、「転職して年収をアップさせる」「副業で稼ぐ」といった方法を検討するのがおすすめです。

業務システム開発やアプリ開発、ゲーム開発において需要の高いC#を扱えるエンジニアは、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。

なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。

今すぐ転職する気がなくとも、とりあえず転職エージェントに無料登録しておくだけで、スカウトが届いたり、思わぬ好待遇の求人情報が送られてきたりするというメリットがあります。

併せて、副業案件を獲得できるエージェントにも登録しておくと、空いている時間を活かして稼げるようなC#の案件を探しやすくなります。

転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。

C#
スポンサーリンク
code-izumiをフォローする