I'm looking to use Expression trees to get property names of a Domain type. This will ultimately be used in an EF context to send Updates for dirty fields. I have the following so far and wanted to confirm that the below is a more a less a complete implementation and whether there is a more flexible/performant way to do the same:
class Message
{
public int ID
{
get;
set;
}
public string Body
{
get;
set;
}
}
internal static class Program
{
public static string GetPropertyName(Expression<Func<Message,object>> exp)
{
string propName = "";
UnaryExpression ue = exp.Body as UnaryExpression;
if(ue != null)
{
propName = (ue.Operand as MemberExpression).Member.Name;
}
MemberExpression me = exp.Body as MemberExpression;
if(me != null)
{
var constExpression = me.Expression as ConstantExpression;
var field = me.Member as FieldInfo;
if (constExpression != null)
if (field != null)
propName = field.GetValue(constExpression.Value).ToString();
}
ConstantExpression ce = exp.Body as ConstantExpression;
if(ce != null)
{
propName = ce.Value.ToString();
}
MethodCallExpression mc = exp.Body as MethodCallExpression;
if(mc != null)
{
//ParameterExpression param = Expression.Parameter(typeof(Message));
ParameterExpression param = mc.Arguments.OfType<ParameterExpression>().FirstOrDefault();
propName = Expression.Lambda(exp.Body, param).Compile().DynamicInvoke(new Message()).ToString();
}
return propName;
}
private static string SomeMethod(Message m)
{
return "ID";
}
private static Expression<Func<Message,object>>[] GetExpressions()
{
string[] props = new[] { "ID", "Name" };
var expressions =
props.Select(p =>
{
Expression<Func<Message,object>> exp = m => p;
return exp;
}).ToArray();
return expressions;
}
public static void Main(string[] args)
{
string str = "id";
Expression<Func<Message, object>> exp1 = m => str;
Expression<Func<Message, object>> exp2 = m => "id";
Expression<Func<Message, object>> exp3 = m => m.ID;
Expression<Func<Message, object>> exp4 = m => SomeMethod(m);
var expressions = GetExpressions();
string s = GetPropertyName(exp1);
s = GetPropertyName(exp2);
s = GetPropertyName(exp3);
s = GetPropertyName(exp4);
foreach (var exp in expressions)
{
s = GetPropertyName(exp);
}
}
}
This SO Post attempts to do something similar but does not seem to cover the use cases above. NOTE: Using "nameof" is not an option here.