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
}
}
comportamento Same differente può essere fondata durante la compilazione Expression.Convert
per questo conversioni:Si tratta di un bug di ExpressionTrees?
Single -> UInt32
Single -> UInt64
Double -> UInt32
Double -> UInt64
sembra strano, non è vero?
< === Aggiunto un po 'la mia ricerca ===>
sto guardato il DynamicMethod
codice MSIL compilato utilizzando DynamicMethod Visualizer e qualche riflessione incidere per ottenere DynamicMethod
dal compilato 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);
E ciò che ottengo è questo codice MSIL:
IL_0000: ldarg.1
IL_0001: conv.i4
IL_0002: ret
E il C# metodo di -compiled pari ha questo corpo:
IL_0000: ldarg.0
IL_0001: conv.u4
IL_0002: ret
Do chiunque vedere ora che ExpressionTrees non compila codice valido per questa conversione?
Thx per la risposta, ma Sì, è importante che il comportamento di overflow è diverso! Qual è una ragione per cui il metodo compilato ha un comportamento diverso dal codice semplice? – ControlFlow
C# non usa altre tecniche eccetto "conv.u4' MScode per convertire i valori in virgola mobile in numeri interi senza segno =) – ControlFlow