The expression <Func <TModel, TValue >> how can I get the name TValue?

//ModelFor(person =>person.Name); public void ModelFor<TModel, TValue>( Expression<Func<TModel, TValue>> expression) { //Result should be "Name" string nameOfTValue = ????; } 
+7
source share
2 answers

EDIT . After your editing, I think that you need the name of the member involved in the expression, assuming, of course, that the expression is, firstly, a member expression.

 ((MemberExpression)expression.Body).Member.Name 

To be more reliable, you can do:

 var memberEx = expression.Body as MemberExpression; if (memberEx == null) throw new ArgumentException("Body not a member-expression."); string name = memberEx.Member.Name; 

(It doesn't matter anymore):

To get System.Type , which represents an argument type of type TValue , you can use typeof .

You probably want:

 typeof(TValue).Name 

But also consider the FullName and AssemblyQualifiedName properties, if necessary.

It really has nothing to do with expression trees; you can use this technique to get the type of a type argument for any general method.

+8
source

@Ani: I don’t think it’s right, I think he wants a parameter name in an expression of type TValue

If this is true ... it only works at level 1, but it can be convenient in any case:

 var nameOfTValue = ((MemberExpression)expression.Body).Member.Name; 

Here is a smarter implementation that needs to deal with several levels:

  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)); } } 

Using:

 var fieldName=PropertyName.For<Customer>(x=>x.Address.Region); //fieldName==Address.Region 

Another trick, this can be combined well with reflection:

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

Allows you to directly set properties with ease, can be useful for test devices:

 var customer=new Customer("firstName","lastName"); customer.Set(x=>x.Name, "different firstName"); 
+9
source

All Articles