私の最初の試みである 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 のプロパティではないことを訴えています。その場合は正しい...しかし、テスト式が偽の場合、条件式の「真の場合」アームが評価されないことを期待していました。明らかにそうではありません。
式ツリーについて私が知らないことは、(それ以上の) 本を埋めるでしょう。しかし、誰かが私がレールから外れているところを指摘できれば、私はそれを感謝します.