For this answer, assume the following is defined:
object myColValueFromTheDatabase = (object)64L;
Expression.Convert
determines statically how the conversion is to be performed. Just like C# does. If you write (uint)myColValueFromTheDatabase
this will not succeed at runtime because unboxing just does not work that way. Expression.Convert
does a simple unboxing attempt as well. That's why it fails.
You would need to do either of the following:
(uint)(long)myColValueFromTheDatabase
Convert.ToUInt32(myColValueFromTheDatabase)
In case (1) you need to unbox to the exact-match type first, then change the bits. Case (2) resolves this using some helper methods. Case (1) is faster.
To do this with the expression API, insert another Expression.Convert
.
This should get you started:
public static T LogValue<T>(T val)
{
Console.WriteLine(val.GetType().Name + ": " + val);
return val;
}
static void Main(string[] args)
{
Expression myColValueFromTheDatabase = Expression.Convert(Expression.Constant(1234L), typeof(object));
myColValueFromTheDatabase = Expression.Call(typeof(Program), "LogValue", new[] { myColValueFromTheDatabase.Type }, myColValueFromTheDatabase); //log
Expression unboxed = Expression.Convert(myColValueFromTheDatabase, typeof(long));
Expression converted = Expression.Convert(unboxed, typeof(uint));
var result = Expression.Lambda<Func<uint>>(converted).Compile()();
Console.WriteLine(result);
}