我第一次尝试在 c# 中编写表达式树并不太顺利:)。这是我要复制的 c# 代码
public static object Test<S, D>(S source, Func<D, object> selector )
where S : class
where D : class
{
D derived = source as D;
object retVal = null;
if( derived != null ) retVal = selector(derived);
return retVal;
}
从概念上讲,如果提供的对象属于派生类,这旨在获取一个对象并将选择器应用于它以返回派生类的属性。
这是我到目前为止所得到的:
public static object OrderByDerivedProperty<S>( S source, Type derivedType, string fieldName )
{
ParameterExpression parameter = Expression.Parameter(typeof(S), "source");
UnaryExpression typeAs = Expression.TypeAs(parameter, derivedType);
ConstantExpression nullConst = Expression.Constant(null);
BinaryExpression isNotNull = Expression.NotEqual(typeAs, nullConst);
ParameterExpression varDest = Expression.Variable(derivedType, "varDest");
ParameterExpression retVal = Expression.Variable(typeof(object), "retVal");
BlockExpression block = Expression.Block(
new[] { varDest, retVal },
Expression.Assign(varDest, typeAs),
Expression.Condition(
isNotNull,
Expression.Assign(retVal, Expression.Property(varDest, fieldName)),
Expression.Assign(retVal, nullConst)
),
retVal
);
LambdaExpression lambda = Expression.Lambda(block, new[] { parameter });
return lambda.Compile().DynamicInvoke(source);
}
我在这里使用了一组稍微不同的参数来简化我的表达方式。
实际上,当 derivedType 是从 S 派生的 Type 时,代码才有效。但是,如果不是——当我期望代码返回 retVal = null 时——它会在以下行爆炸:
Expression.Assign(retVal, Expression.Property(varDest, fieldName)),
抱怨 fieldName 不是 varDest 的属性。在那种情况下这是正确的......但如果测试表达式为假,我期望条件表达式的“如果为真”臂不会被评估。显然不是这样。
我对表达式树的不了解会填满(超过)一本书。但是,如果有人能指出我要在哪里出轨,我将不胜感激。