I discovered the TypedReflector
on Daniel Cazzulino’s Blog. In essence, a simplified version of the code looks like:
public static class Reflector
{
public static PropertyInfo GetProperty<T, TRet>(Expression<Func<T, TRet>> expression)
{
return GetMemberInfo(expression) as PropertyInfo;
}
public static FieldInfo GetField<T, TRet>(Expression<Func<T, TRet>> expression)
{
return GetMemberInfo(expression) as FieldInfo;
}
public static MethodInfo GetMethod<T, TRet>(Expression<Func<T, TRet>> expression)
{
return GetMemberInfo(expression) as MethodInfo;
}
public static MemberInfo GetMemberInfo(Expression memberInfoExpression)
{
Expression lambdaBodyExpression = ((LambdaExpression)memberInfoExpression).Body;
switch (lambdaBodyExpression.NodeType)
{
case ExpressionType.MemberAccess:
return ((MemberExpression)lambdaBodyExpression).Member;
case ExpressionType.Call:
return ((MethodCallExpression)lambdaBodyExpression).Method;
default:
throw new ArgumentException("Unsupported NodeType");
}
}
}
This class allows me to write the following:
PropertyInfo namePropertyInfo = Reflector.GetProperty<Person, string>(p => p.Surname);
Not only can i be sure that the lambda (and thus the namePropertyInfo.Invoke) will always return a string, i can also use it to avoid ‘hardcoded’ propertynames:
//const string SurnameProperty = "Surname"; //comboBox1.DisplayMember = SurnameProperty; comboBox1.DisplayMember = Reflector.GetProperty<Person, string>(p => p.Surname).Name;