1つのオブジェクトをパラメーターとして受け取り、最終的にオブジェクトを返すLambdaExpressionがあります。テストの目的で、オブジェクトとしてボックス化されたDateTimeを返すLambda(実際に渡したものと一致するようにロングハンドで作成された)を次に示します。これを処理するために、LambdaExpressionはXmlNodeを受け取り、オブジェクトを返します。オブジェクトを返す必要があります。実際の戻りタイプは次のいずれかになります。DateTime、bool、int、decimal、XmlDocument [これまでのところ]一般的な考え方は、パーサーのどこかでこのラムダが作成され、そこから値を抽出するというものです。パラメータを入力し、入力されたものを返しますが、オブジェクトでボックス化されています。
XmlNode node = null;
ParameterExpression instanceExpression = Expression.Parameter(typeof(DynamicNode), "instance");
ParameterExpression result = Expression.Parameter(typeof(object), "result");
LabelTarget blockReturnLabel = Expression.Label(typeof(object));
BlockExpression block = Expression.Block(
typeof(object),
new[] { result },
Expression.Assign(result, Expression.Convert(Expression.Constant(DateTime.Now.AddSeconds(-1)), typeof(object))),
Expression.Return(blockReturnLabel, result),
Expression.Label(blockReturnLabel, Expression.Constant(-2, typeof(object))));
LambdaExpression lax = Expression.Lambda<Func<XmlNode, object>>(block, instanceExpression);
コードの後半で、<、<=、>、> =、==、および!=を評価しているため、このLambdaExpressionの結果を別の式と比較します。
通常、LambdaExpressionはExpression.LessThanの左側にあると想定できますが、ほとんどすべての式である可能性がありますが、型指定されていると想定します。つまり、ConstantExpressionまたは同様のものである可能性がありますが、タイプがあります。
これは、Expression.Invokeが呼び出されたときにLambdaExpressionがオブジェクトを返し、RHSがそのタイプであるため、Expression.LessThan[たとえば]が失敗することを意味します。
LambdaExpressionから返されたオブジェクト内にボックス化されたタイプが、実際には右側のタイプに匹敵すると仮定します。例えば
(object)5 < 6
ボックス化されたタイプとボックス化されていないタイプをクラッシュせずに比較できる式を作成するにはどうすればよいですか?私はlinqpadでさまざまな順列を試しました。これには、通常のc#でこれを書き込もうとすることも含まれます。つまり、式を使用せず、if-then-elseをネストするだけですが、正しく機能させることができませんでした。通常、私はおそらく次のようなものを書くでしょう:
/*
int i = 3;
object o = (object)i;
int compare = 4;
*/
DateTime dt = DateTime.Now;
object o = (object)dt;
DateTime compare = DateTime.Now.AddSeconds(1);
bool b = false;
if(o.GetType().IsAssignableFrom(compare.GetType()))
{
if(o is int)
{
b = (int)o < (int)(object)compare;
}
if(o is DateTime)
{
b = (DateTime)o < (DateTime)(object)compare;
}
if(o is decimal)
{
b = (decimal)o < (decimal)(object)compare;
}
}
Console.WriteLine(b);
これにより、oとcompareが実際には同じタイプであり、そのうちの1つがオブジェクトとしてボックス化されていると仮定すると、<操作を実行できます。
ですから、私の質問は、左側にLambdaExpressionがあり、右側にExpressionがある場合、上記のコードをどのように記述すればよいかということです[2つが同じタイプでない場合、結果としてfalseの方がクラッシュよりも優れています]
誰かが助けてくれることを願っています、
ガレス