3

给定两条短裤 ( System.Int16)

short left = short.MaxValue;
short right = 1;

我想OverflowException在添加它们时得到一个。

checked(left+right)

不起作用,因为结果left+rightInt32.

checked((short)(left+right))

按预期工作。

我的问题是,使用表达式树,“技巧”不起作用:

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();

调用f()不会抛出溢出异常而是返回-32768。怎么了?

4

2 回答 2

4

问题是添加作为short + short 完成的(它可能存在于IL中,即使它在C#中不存在) - 然后单独执行转换。这个完整的程序显示了这一点 - 即使没有转换,结果也是 -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());
    }
}

如果你让它做一个 int + int 加法然后转换,它会抛出一个溢出异常:

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());
    }
}

我不知道为什么AddChecked不起作用...这看起来像一个错误:(使用允许指定方法的重载可能会起作用,但我不确定...

于 2008-12-29T17:23:42.640 回答
0

谢谢。

换句话说:您在 C# 中看到的内容不能 1:1 转换为表达式树。我想知道为什么他们决定隐含地将两条短裤的总和扩大到 int。

于 2008-12-29T17:30:11.553 回答