2011-01-05 40 views
7
//ModelFor(person =>person.Name); 
public void ModelFor<TModel, TValue>(
    Expression<Func<TModel, TValue>> expression) 
{ 
    //Result should be "Name" 
    string nameOfTValue = ????;  
} 
+0

你需要澄清一下,你想要的类型TValue的名称,或者你想要的名称的p表达中的参数? – casperOne 2011-01-05 16:10:57

+0

@casperOne - 我编辑 – Freshblood 2011-01-05 16:12:24

+0

@casperOne'TValue'总是返回类型而不是普通参数。 – CodesInChaos 2011-01-05 16:13:00

回答

8

编辑:编辑完成后,我认为你需要表达式中涉及的成员的名字,假设表达式首先是成员表达式。

((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; 

(不再相关):

要获得System.Type表示TValue类型的类型 - 参数,您可以使用typeof运算符。

你可能想:如果合适

typeof(TValue).Name 

还要考虑FullNameAssemblyQualifiedName性能。

这实际上与表达式树无关;您可以使用此技术获取任何通用方法的类型参数类型。

+0

哇,我们完全写了相同的答案 – CodesInChaos 2011-01-05 16:07:24

+1

我不认为这是正确的,我认为他希望参数的名称在TValue类型的表达式中。 – casperOne 2011-01-05 16:10:32

+0

@casperOne:你可能是对的;我不确定。让我们等待澄清。 – Ani 2011-01-05 16:12:57

9

@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"); 
+0

不错,我真的很喜欢它! – Raffaeu 2011-01-19 14:37:48

相关问题