Expression> How can I find out who TValue is?

.net c# expression-trees

Question

//ModelFor(person =>person.Name);
public void ModelFor<TModel, TValue>(
    Expression<Func<TModel, TValue>> expression)
{
    //Result should be "Name"
    string nameOfTValue = ????;     
}
1
7
1/5/2011 4:17:31 PM

Accepted Answer

EDIT: After your update, assuming of course that the expression is a member-expression in the first place, I believe you want the name of the member participating in the expression.

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

You can: to strengthen yourself.

var memberEx = expression.Body as MemberExpression;

if (memberEx == null)
     throw new ArgumentException("Body not a member-expression.");

string name = memberEx.Member.Name;

(No longer applicable)

To obtainSystem.Type it illustrates the kind of theTValue You may use the typeof operator to provide a type-argument.

You likely desire:

typeof(TValue).Name

But take into account theFullName and AssemblyQualifiedName if appropriate, properties.

You may use this method to determine the type of a type-argument for the any generic method; it truly has nothing to do with expression trees.

8
1/5/2011 4:17:21 PM

Popular Answer

@Ani: I don't think this is right, I think that he wants the name of the parameter in the expression of type TValue

If this is accurate, this only works at the level level, but it could still be useful:

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

Here is a cleverer approach that ought to be able to handle various 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));
    }
  }

Usage:

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

Another technique, this works 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;
}

easily enables direct property setting; handy for test setups

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


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow