Expression.addChecked و System.int16.
-
29-08-2019 - |
سؤال
إعطاء اثنين من السراويل (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
. وبعد ماذا دهاك؟
المحلول
المشكلة هي أن الإضافة يكون يجري القيام به باعتبارها قصيرة + قصيرة (والتي من المفترض أن تكون موجودة في 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
لا يعمل على الرغم من ... يشبه الخطأ :( من الممكن استخدام الحمل الزائد الذي يسمح للطريقة المحددة ستعمل, ، ولكني لست متأكدا...
نصائح أخرى
شكرا.
مع كلمات أخرى: ما تراه في C # لا يمكن ترجمته 1: 1 للتعبير الأشجار. أتساءل لماذا قرروا توسيع مجموع شورتين إلى int.