Information Technology Reference
In-Depth Information
Expression convertedRight = rightOperand;
if ( typeof (T2) != typeof (TResult))
{
convertedRight = Expression .Convert(rightOperand,
typeof (TResult));
}
var body = Expression .Add(convertedLeft, convertedRight);
var adder = Expression .Lambda< Func <T1, T2, TResult>>(
body, leftOperand, rightOperand);
return adder.Compile()(left, right);
}
That will fix all the problems with any addition that needs a conversion,
like adding doubles and ints , or adding a double to string with the
result being a string. However, it breaks valid usages where the parame-
ters should not be the same as the result. In particular, this version would
not work with the example above adding a TimeSpan to a DateTime. With
a lot more code, you could solve this. However, at that point, you've pretty
much reimplemented the code that handles dynamic dispatch for C# (see
Item 41). Instead of all that work, just use dynamic.
Yo u s h o u l d u s e t h e e x p r e s s i o n v e r s i o n f o r t h o s e t i m e s w h e n t h e o p e r a n d s
and the result are the same. That gives you generic type parameter inference
and fewer permutations when the code fails at runtime. Here's the version
I would recommend to use Expression for implementing runtime dispatch:
public static class BinaryOperators <T>
{
static Func <T, T, T> compiledExpression;
public static T Add(T left, T right)
{
if (compiledExpression == null )
createFunc();
return compiledExpression(left, right);
}
private static void createFunc()
{
var leftOperand = Expression .Parameter( typeof (T),
"left" );
Search WWH ::




Custom Search