Reputation: 2066
I'm trying to build some objects based on properties coming from another object. The class of the objects I need to build is
public class Data
{
public string Attribute { get; set; }
public string Value{ get; set; }
}
And the attribute will be the name of the property (and the value its value)
So I was trying to use Expressions trees to make a method that I can use for avoiding hard coding that attribute
Up to the moment I came to these couple of methods, based on a couple of posts I was reading on the net
public static string GetName<T>(Expression<Func<T>> e)
{
var member = (MemberExpression)e.Body;
return member.Member.Name;
}
public static Data BuildData<T>(Expression<Func<T>> e, appDetailCategory category)
{
var member = (MemberExpression)e.Body;
Expression strExpr = member.Expression;
var name = member.Member.Name;
var value = Expression.Lambda<Func<string>>(strExpr).Compile()();
return new Data
{
Attribute = name,
Value = value
};
}
But the line I'm trying to set the value raises an exception:
Expression of type 'AutomapperTest.Program+DecisionRequest' cannot be used for return type 'System.String'
I'm pretty sure this message it's supposed to make the error obvious but it's not for me
UPDATE:
I'm calling it this way
private static Data[] GetApplicatonDetailsFromRequest(DecisionRequest request)
{
BuildData(() => request.PubID)
//...
}
Upvotes: 1
Views: 140
Reputation: 62472
It looks like your problem is that the type of PubID
isn't a string. You've got two options, either change Data
to store the value as an object
or call ToString
on the value returned from the property and store it. For example:
public static Data BuildData<T>(Expression<Func<T>> e)
{
var member = (MemberExpression)e.Body;
var name = member.Member.Name;
Func<T> getPropertyValue=e.Compile();
object value = getPropertyValue();
return new Data
{
Attribute = name,
Value = value.ToString()
};
}
Note that to get the value you can just compile the Func
expression.
Upvotes: 0
Reputation: 5007
Must be member, not member.Expression.
public static Data BuildData<T>(Expression<Func<T>> e, appDetailCategory category)
{
var member = (MemberExpression)e.Body;
var name = member.Member.Name;
var value = Expression.Lambda<Func<string>>(member).Compile()();
return new Data
{
Attribute = name,
Value = value
};
}
Upvotes: 1