//ModelFor(person =>person.Name);
public void ModelFor<TModel, TValue>(
Expression<Func<TModel, TValue>> expression)
{
//Result should be "Name"
string nameOfTValue = ????;
}
編輯 :編輯後,我認為你想要表達式中涉及的成員的名稱,當然假設表達式首先是成員表達式。
((MemberExpression)expression.Body).Member.Name
為了更加強大,您可以:
var memberEx = expression.Body as MemberExpression;
if (memberEx == null)
throw new ArgumentException("Body not a member-expression.");
string name = memberEx.Member.Name;
(不再相關):
要獲取表示TValue
類型參數類型的System.Type
,可以使用typeof
運算符。
你可能想要:
typeof(TValue).Name
但如果合適,還要考慮FullName
和AssemblyQualifiedName
屬性。
這與表達樹無關;您可以使用此技術獲取任何泛型方法的類型參數的類型。
@Ani:我不認為這是對的,我認為他想在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");