Given two shorts (System.Int16)
short left = short.MaxValue;
short right = 1;
I want to get an OverflowException when adding them.
checked(left+right)
does not work, because the result of left+right is an Int32.
checked((short)(left+right))
works as expected.
My problem is that, using Expression Trees, the "trick" doesn't work:
var a = Expression.Constant(left);
var b = Expression.Constant(right);
var sum = Expression.ConvertChecked(Expression.Add(a, b), typeof(short));
var l = Expression.Lambda(sum);
var f = (Func<short>)l.Compile();
Calling f() does not throw an overflow exception but returns -32768. What's wrong?
The problem is that the addition is being done as short + short (which presumably exists in IL even if it doesn't exist in C#) - and then the conversion is performed separately. This is shown by this complete program - even without the conversion, the result is -32768:
using System;
using System.Linq.Expressions;
class Test
{
static void Main(string[] args)
{
short left = short.MaxValue;
short right = 1;
var a = Expression.Constant(left);
var b = Expression.Constant(right);
var sum = Expression.Add(a, b);
var convert = Expression.ConvertChecked(sum, typeof(short));
var convertLambda = Expression.Lambda<Func<short>>(convert);
var convertFunc = convertLambda.Compile();
Console.WriteLine("Conversion: {0}", convertFunc());
var sumLambda = Expression.Lambda<Func<short>>(sum);
var sumFunc = sumLambda.Compile();
Console.WriteLine("Sum: {0}", sumFunc());
}
}
If you make it do an int + int addition and then the conversion, it will throw an overflow exception:
using System;
using System.Linq.Expressions;
class Test
{
static void Main(string[] args)
{
short left = short.MaxValue;
short right = 1;
var a = Expression.Constant((int) left);
var b = Expression.Constant((int) right);
var sum = Expression.Add(a, b);
var convert = Expression.ConvertChecked(sum, typeof(short));
var convertLambda = Expression.Lambda<Func<short>>(convert);
var convertFunc = convertLambda.Compile();
Console.WriteLine("Conversion: {0}", convertFunc());
var sumLambda = Expression.Lambda<Func<int>>(sum);
var sumFunc = sumLambda.Compile();
Console.WriteLine("Sum: {0}", sumFunc());
}
}
I don't know why AddChecked doesn't work though... that looks like a bug :( It's possible that using the overload which allows the Method to specified would work, but I'm not sure...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With