After some thinking, I'm happy that thanks to the question and some answers I have resolved an old problem of mine: using operations on generic T:
First the example with Cast (as requested by the OP)
public static class Cast<T, U>
{
public static readonly Func<T, U> Do;
static Cast()
{
var par1 = Expression.Parameter(typeof(T));
Do = Expression.Lambda<Func<T, U>>(Expression.Convert(par1, typeof(U)), par1).Compile();
}
}
And then an example with multiplication:
public static class Multiply<T>
{
public static readonly Func<T, T, T> Do;
static Multiply()
{
var par1 = Expression.Parameter(typeof(T));
var par2 = Expression.Parameter(typeof(T));
Do = Expression.Lambda<Func<T, T, T>>(Expression.Multiply(par1, par2), par1, par2).Compile();
}
}
The use is quite simple:
int x = Conv<T, int>.Do(someTValue);
in the end a static class is created, with a single field that is a readonly static property named Do
that is a delegate that "points" to an operation built with an Expression tree.
The multiplication is similar:
T res = Multiply<T, T>.Do(someTValue1, someTValue2);
The multiplication is somewhat 3x slower in the general case than a direct multiplication (in Release mode, no debugging).
Clearly doing the other operations is simple by starting from Multiplication
(it's interesting that I knew quite well of Expression
trees, but I hadn't ever thought of using static classes as "dictionaries" for containing the various types. I always did something like Dictionary<Type, Delegate>
instead of letting the .NET "handle" the Dictionary
through generic class specialization.)