Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expression.Body as MemberExpression returns null for primitive property

Tags:

c#

lambda

linq

I am using this code to set the value of a property via reflection :

public static void Set<T>(this T target, Expression<Func<T, object>> memberLamda, object value)
{
    var memberSelectorExpression = memberLamda.Body as MemberExpression;
    if (memberSelectorExpression != null)
    {
        var property = memberSelectorExpression.Member as PropertyInfo;
        if (property != null)
        {
            property.SetValue(target, value, null);
        }
    }
}

But for some reason when I do :

myObject.Set(x=>x.ID, 1);

Where ID is of type int, I can see that memberSelectorExpression is null. However I have no issue with properties of a reference type.

I am not very familiar yet with expression trees, what I am doing wrong ?

like image 924
tobiak777 Avatar asked Oct 15 '25 17:10

tobiak777


2 Answers

The solution is to use the following signature :

public static void Set<T, TProp>(this T target, Expression<Func<T, TProp>> memberLamda, 
  TProp value)

To make sure a MemberExpression is correctly inferred. The "object" generic constraint is not specific enough.

like image 114
tobiak777 Avatar answered Oct 18 '25 06:10

tobiak777


The thing to be aware of is that your expression body will most likely be wrapped in a Convert expression, representing the fact that your property is being implicitly cast as an object. So you'll probably need code something like this in your Setmethod.

var expressionBody = memberLamda.Body;
if (expressionBody is UnaryExpression expression && expression.NodeType == ExpressionType.Convert)
{
    expressionBody = expression.Operand;
}
var memberSelectorExpression = (MemberExpression)expressionBody;
like image 41
StriplingWarrior Avatar answered Oct 18 '25 07:10

StriplingWarrior