How can I adapt the method below to work when the lambda expression refers to the actual instance itself?
e.g. instead of
x => x.Name
the expression is
x => x
so if I had some class "Car" I could return the string "Car" instead of only being able to operate on its properties (e.g. Car.Colour)
The method:
public static string GetMemberName(Expression expression)
{
if (expression is LambdaExpression)
expression = ((LambdaExpression)expression).Body;
if (expression is MemberExpression)
{
var memberExpression = (MemberExpression)expression;
if (memberExpression.Expression.NodeType ==
ExpressionType.MemberAccess)
{
return GetMemberName(memberExpression.Expression)
+ "."
+ memberExpression.Member.Name;
}
return memberExpression.Member.Name;
}
if (expression is UnaryExpression)
{
var unaryExpression = (UnaryExpression)expression;
if (unaryExpression.NodeType != ExpressionType.Convert)
throw new Exception(string.Format(
"Cannot interpret member from {0}",
expression));
return GetMemberName(unaryExpression.Operand);
}
throw new Exception(string.Format(
"Could not determine member from {0}",
expression));
}
i.e. I want something like:
if (expression is SomeExpressionThatReturnsAnInstance)
{
return (name of type of instance);
}
I've traced this back to the construction of the Expression. It doesn't really contain any instance information, and no way to get the type name.
static Expression<Func<object, object>> thisObject = x => x;
So there's no way that a type name can be derived from an Expression that doesn't even have a type (other than object).
The method used to generate an expression that returns a property name:
LambdaExpression BuildExpression(Type rootType, string propertyName)
{
try
{
var properties = propertyName.Split('.');
ParameterExpression arg = Expression.Parameter(rootType, "x");
Expression expr = arg;
foreach (string property in properties)
{
PropertyInfo propertyInfo = rootType.GetProperty(property);
if (propertyInfo == null)
return null;
expr = Expression.Property(expr, propertyInfo);
rootType = propertyInfo.PropertyType;
}
return Expression.Lambda(expr, arg);
}
catch (System.Exception ex)
{
return null;
}
}