3

与えられた 2 つのショーツ ( System.Int16)

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

OverflowExceptionそれらを追加するときに取得したい。

checked(left+right)

left+rightの結果は であるため、機能しませんInt32

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(C#に存在しない場合でもおそらくILに存在する)として実行されていることです。その後、変換が個別に実行されます。これは、この完全なプログラムによって示されます-変換がなくても、結果は-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で変換することはできません。なぜ彼らは暗黙のうちに2つのショートの合計をintに広げることにしたのだろうか。

于 2008-12-29T17:30:11.553 に答える