@ Ани: Я не думаю, что это правильно, я думаю, что он хочет имя параметра в выражении типа TValue
Если это правда ... это работает только на 1 уровень, но в любом случае может пригодиться:
var nameOfTValue = ((MemberExpression)expression.Body).Member.Name;
Вот более разумная реализация, которая должна иметь возможность работать с несколькими уровнями:
public class PropertyName{
public static string For<T>(
Expression<Func<T,object>> expression){
var body=expression.Body;
return GetMemberName(body);
}
public static string For(
Expression<Func<object>> expression){
var body=expression.Body;
return GetMemberName(body);
}
public static string GetMemberName(
Expression expression){
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));
}
}
Использование:
var fieldName=PropertyName.For<Customer>(x=>x.Address.Region);
//fieldName==Address.Region
Еще один трюк, который можно красиво сочетать с отражением:
public static T Set<T,TProp>(this T o,
Expression<Func<T,TProp>> field,TProp value){
var fn=((MemberExpression)field.Body).Member.Name;
o.GetType().GetProperty(fn).SetValue(o,value,null);
return o;
}
Позволяет легко устанавливать свойства, может быть полезен для тестовых приборов:
var customer=new Customer("firstName","lastName");
customer.Set(x=>x.Name, "different firstName");