mitomed
mitomed

Reputation: 2066

Get value and name of property of an object

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

Answers (2)

Sean
Sean

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

Der_Meister
Der_Meister

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

Related Questions