Help us understand the problem. What is going on with this article?

[.NET] リフレクション スニペット集

More than 1 year has passed since last update.

よく使いそうなリフレクションのスニペットを集めてみました。
※型を明示するため、var はあえて使用していません(一部除く)。
※安全性と処理速度を考慮し、利用は必要最低限に絞りましょう。

インスタンス生成

public/引数なし

Sample sample = Activator.CreateInstance<Sample>();

public/引数あり

object[] args = new object[] { true };
Sample sample = (Sample)Activator.CreateInstance(typeof(Sample), args);

非 public/引数あり

object[] args = new object[] { 1 };
Sample sample = (Sample)Activator.CreateInstance(typeof(Sample), BindingFlags.NonPublic | BindingFlags.Instance, null, args, null);

フィールドアクセス

非 public/インスタンスフィールド

※静的フィールドの場合、BindingFlags.Instance → BindingFlags.Static

Sample sample = new Sample();
FieldInfo field = sample.GetType().GetField("privateField", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(sample, true);
bool fieldValue = (bool)field.GetValue(sample);

プロパティアクセス

非public/インスタンスプロパティ

※静的フィールドの場合、BindingFlags.Instance → BindingFlags.Static

Sample sample = new Sample();
PropertyInfo property = sample.GetType().GetProperty("PrivateProperty", BindingFlags.NonPublic | BindingFlags.Instance);
property.SetValue(sample, true, null);
bool propertyValue = (bool)property.GetValue(sample, null);

メソッド呼び出し

非 public/インスタンスメソッド

Sample sample = new Sample();
MethodInfo method = sample.GetType().GetMethod("PrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance);
object[] args = new object[] { 1 };
bool returnValue = (bool)method.Invoke(sample, args);

ref 引数

// 引数を false から true に変える ChangeByRefToTrue メソッドを呼び出す。
Sample sample = new Sample();
Type[] paramTypes = new Type[] { typeof(bool).MakeByRefType() };
MethodInfo method = sample.GetType().GetMethod("ChangeByRefToTrue", BindingFlags.NonPublic | BindingFlags.Instance, null, paramTypes, null);
bool inValue = false;
object[] args = new object[] { inValue };
method.Invoke(sample, args);
bool outValue = (bool)args[0];

Assert.IsFalse(inValue);
Assert.IsTrue(outValue);

属性情報

SampleAttribute attribute = (SampleAttribute)Attribute.GetCustomAttribute(typeof(Sample), typeof(SampleAttribute));
bool attributeProperty = attribute.Foo;

アセンブリ情報

現在実行中のコードを格納しているアセンブリ

Assembly executingAssembly = Assembly.GetExecutingAssembly();

現在実行中のメソッドを呼び出したメソッドのアセンブリ

Assembly callingAssembly = Assembly.GetCallingAssembly();

実行可能ファイルのアセンブリ

※アンマネージアプリケーションから読み込まれている場合、null

Assembly entryAssembly = Assembly.GetEntryAssembly();

実行可能ファイルのパス

string exePath = Application.ExecutablePath;

型情報

型判定

Type type = typeof(Sample);
// 列挙型か。
bool isEnum = type.IsEnum;
// 値型か。
bool isValueType = type.IsValueType;
// Nullを許可する値型か。
bool isNullableValueType = (Nullable.GetUnderlyingType(type) != null);

型名

Assert.AreEqual("String", typeof(String).Name);

型名(コンパイル時解決)

※C# 6.0 / VB 2015~ ならリフレクションよりまずこちらを検討

Assert.AreEqual("String", nameof(String));

メソッド情報

現在のメソッド名

string currentMethodName = MethodBase.GetCurrentMethod().Name;

呼び出し元のメソッド名

※コンパイラによってインライン展開されていないことが前提です。
※.NET 4.5~ は、CallerMemberNameAttribute を使用して引数から取得できます。

StackFrame frame = new StackFrame(1);
string callerMethodName = frame.GetMethod().Name;

メソッド名(コンパイル時解決)

※C# 6.0 / VB 2015~ ならリフレクションよりまずこちらを検討

Assert.AreEqual("IndexOf", nameof(String.IndexOf));

プロパティ情報

現在のプロパティ名

public bool Property
{
    get
    {
        MethodBase accessor = MethodBase.GetCurrentMethod();
        string propertyName = GetProperty(accessor).Name;
        return true;
    }
}

アクセサからプロパティ情報を取得するメソッド

public static PropertyInfo GetProperty(MethodBase accessor)
{
    PropertyInfo[] properties = accessor.DeclaringType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
    foreach (PropertyInfo property in properties)
    {
        MethodInfo[] methods = property.GetAccessors(true);
        foreach (MethodInfo method in methods)
        {
            if (method == accessor)
            {
                return property;
            }
        }
    }
    return null;
}

Lambda 式からプロパティ名を取得するメソッド

public static string GetPropertyName<TObject, TProperty>(Expression<Func<TObject, TProperty>> getter)
{
    var lambda = (LambdaExpression)getter;
    var memberExpression = lambda.Body as MemberExpression;

    if (memberExpression == null)
    {
        // TProperty が object の場合、ボックス化によって UnaryExpression となる。
        var body = (UnaryExpression)lambda.Body;
        memberExpression = (MemberExpression)body.Operand;
    }

    return memberExpression.Member.Name;
}

// 使用例
string propertyName = GetPropertyName((Sample s) => s.PublicProperty);

プロパティ名(コンパイル時解決)

※C# 6.0 / VB 2015~ ならリフレクションよりまずこちらを検討

Assert.AreEqual("Length", nameof(String.Length));
CodeOne
【品質と生産性にこだわるシステム開発】 .NET(C#/VB.NET)専門・リモート開発歴10年。即日・1時間から頼める常駐しないエンジニア。確かな技術で開発チームを手堅くサポートいたします。
https://codeone.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした