This is Oliver Hanappi's static reflection code he posted on stackoverflow
private static string GetMemberName(Expression expression)
{
switch (expression.NodeType)
{
case ExpressionType.MemberAccess:
var memberExpression = (MemberExpression)expression;
var supername = GetMemberName(memberExpression.Expression);
if (String.IsNullOrEmpty(supername))
return memberExpression.Member.Name;
return String.Concat(supername, '.', memberExpression.Member.Name);
case ExpressionType.Call:
var callExpression = (MethodCallExpression)expression;
return callExpression.Method.Name;
case ExpressionType.Convert:
var unaryExpression = (UnaryExpression)expression;
return GetMemberName(unaryExpression.Operand);
case ExpressionType.Parameter:
return String.Empty;
default:
throw new ArgumentException("The expression is not a member access or method call expression");
}
}
I have the public wrapper methods:
public static string Name<T>(Expression<Action<T>> expression)
{
return GetMemberName(expression.Body);
}
public static string Name<T>(Expression<Func<T, object>> expression)
{
return GetMemberName(expression.Body);
}
then added my own method shortcuts
public static string ClassMemberName<T>(this T sourceType,Expression<Func<T,object>> expression)
{
return GetMemberName(expression.Body);
}
public static string TMemberName<T>(this IEnumerable<T> sourceList, Expression<Func<T,object>> expression)
{
return GetMemberName(expression.Body);
}
What are examples of code that would necessitate or take advantage of the different branches in the GetMemberName(Expression expression)
switch? what all is this code capable of making strongly typed?
MemberAccess
:foo => foo.SomeField
orfoo => foo.SomeProperty
Call
:foo => foo.SomeMethod(...)
Parameter
:foo => foo
Convert
:foo => (int)foo.Something
(perhaps implicit)