C# Expression.Body as MemberExpression为基元属性返回null
我使用此代码通过反射设置属性的值:C# Expression.Body as MemberExpression为基元属性返回null,c#,linq,lambda,C#,Linq,Lambda,我使用此代码通过反射设置属性的值: public static void Set<T>(this T target, Expression<Func<T, object>> memberLamda, object value) { var memberSelectorExpression = memberLamda.Body as MemberExpression; if (memberSelectorExpression != null)
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);
}
}
}
其中ID的类型为int,我可以看到memberSelectorExpression为null。但是,我对引用类型的属性没有问题
我还不太熟悉表达式树,我做错了什么?解决方案是使用以下签名:
public static void Set<T, TProp>(this T target, Expression<Func<T, TProp>> memberLamda,
TProp value)
公共静态无效集(此T目标,表达式memberLamda,
TProp值)
以确保正确推断MemberExpression。“对象”通用约束不够具体 需要注意的是,表达式体很可能被包装在转换表达式中,表示属性被隐式转换为对象的事实。因此,您可能需要在Setmethod中编写类似的代码
var expressionBody = memberLamda.Body;
if (expressionBody is UnaryExpression expression && expression.NodeType == ExpressionType.Convert)
{
expressionBody = expression.Operand;
}
var memberSelectorExpression = (MemberExpression)expressionBody;
看看实际的表达式树,看看表达式实际上是什么,因为您现在知道它不是
MemberExpression
@Servy好主意,谢谢!或者,如果您的代码很快就会失败,如果正文不是成员表达式,那么只需强制转换,而不是使用as
。@JonSkeet另一个好主意,谢谢。。。我有一种感觉,我累了,这看起来越来越像一件小事question@Servy表达式主体是Convert(x.Id)类型。如何从中提取Propertyinfo?关于.NET核心,还有其他选择吗?似乎TProp在那里不可用。但问题是相同的,使用表达式I Get null…@Lion它将始终可用,TProp表示一个泛型类型,它是一个编译器功能(独立于.NET Core)-
var expressionBody = memberLamda.Body;
if (expressionBody is UnaryExpression expression && expression.NodeType == ExpressionType.Convert)
{
expressionBody = expression.Operand;
}
var memberSelectorExpression = (MemberExpression)expressionBody;