よく使いそうなリフレクションのスニペットを集めてみました。
※型を明示するため、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));