using System;
using System.Linq.Expressions;
class Program
{
static void Main()
{
Expression<Func<float, uint>> expr = x => (uint) x;
Func<float,uint> converter1 = expr.Compile();
Func<float,uint> converter2 = x => (uint) x;
var aa = converter1(float.MaxValue); // == 2147483648
var bb = converter2(float.MaxValue); // == 0
}
}
hành vi tương tự khác nhau có thể được thành lập khi biên dịch Expression.Convert
cho các chuyển đổi này:Đây có phải là lỗi ExpressionTrees không?
Single -> UInt32
Single -> UInt64
Double -> UInt32
Double -> UInt64
Trông lạ, phải không?
< === thêm một số nghiên cứu của tôi ===>
Tôi nhìn vào biên soạn DynamicMethod
mã MSIL sử dụng DynamicMethod Visualizer và một số phản ánh hack để có được DynamicMethod
từ biên soạn Expression<TDelegate>
:
Expression<Func<float, uint>> expr = x => (uint) x;
Func<float,uint> converter1 = expr.Compile();
Func<float,uint> converter2 = x => (uint) x;
// get RTDynamicMethod - compiled MethodInfo
var rtMethodInfo = converter1.Method.GetType();
// get the field with the reference
var ownerField = rtMethodInfo.GetField(
"m_owner", BindingFlags.NonPublic | BindingFlags.Instance);
// get the reference to the original DynamicMethod
var dynMethod = (DynamicMethod) ownerField.GetValue(converter1.Method);
// show me the MSIL
DynamicMethodVisualizer.Visualizer.Show(dynMethod);
Và những gì tôi nhận được là mã MSIL này:
IL_0000: ldarg.1
IL_0001: conv.i4
IL_0002: ret
Và C# phương pháp -compiled bình đẳng có thân hình này:
IL_0000: ldarg.0
IL_0001: conv.u4
IL_0002: ret
Đừng ai nhìn thấy bây giờ mà ExpressionTrees không biên dịch mã hợp lệ cho chuyển đổi này?
Thx cho câu trả lời của bạn, nhưng có, điều quan trọng là hành vi tràn là khác nhau! Lý do cho phương pháp được biên dịch có hành vi khác với mã đơn giản là gì? – ControlFlow
C# không sử dụng các kỹ thuật khác ngoại trừ mã vạch MSIL 'conv.u4' để chuyển đổi các giá trị dấu phẩy động thành số nguyên không dấu =) – ControlFlow