3 Stimmen

Expression.AddChecked und System.Int16

Bei zwei kurzen Hosen ( System.Int16 )

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

Ich möchte eine OverflowException wenn sie hinzugefügt werden.

checked(left+right)

funktioniert nicht, da das Ergebnis von left+right es un Int32 .

checked((short)(left+right))

funktioniert wie erwartet.

Mein Problem ist, dass der "Trick" bei der Verwendung von Expression Trees nicht funktioniert:

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

Aufruf von f() löst keine Überlaufausnahme aus, sondern gibt -32768 . Was ist los?

4voto

Jon Skeet Punkte 1325502

Das Problem ist, dass der Zusatz es als short + short (was vermutlich in IL existiert, auch wenn es in C# nicht existiert) - und dann wird die Konvertierung separat durchgeführt. Dies wird durch dieses vollständige Programm gezeigt - auch ohne die Konvertierung, ist das Ergebnis -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());
    }
}

Wenn Sie eine Addition von int + int und dann die Konvertierung durchführen, kommt es zu einer 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());
    }
}

Ich weiß nicht, warum AddChecked funktioniert allerdings nicht... das sieht nach einem Fehler aus :( Es ist möglich, dass die Verwendung von die Überladung, die es erlaubt, die Methode zu spezifizieren, würde funktionieren aber ich bin mir nicht sicher...

0voto

Rauhotz Punkte 7594

Danke.

Mit anderen Worten: Was Sie in C# sehen, lässt sich nicht 1:1 auf Expression Trees übertragen. Ich frage mich warum sie sich entschieden haben, die Summe von zwei shorts implizit zu int. zu erweitern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X