Я заметил это поведение на # компилятор по умолчанию C, VS 2017 RC EnterpriseВозможно избыточно опкод, когда явно базовый тип отливать
При двойном/поплавок отливают себе известный тип Conv.R8/Conv.R4 излучается. Однако, если объект или тип неплавающей точки забрасываются, ничего не происходит.
Примеры, приведенные ниже, составлены по адресу release
. В debug
IL аналогичен. Образец C# Код:
private double _Double;
private float _Float;
private int _Int;
private object _Object;
private int IntConvertToInt()
{
int x = (int)_Int; //
return x;
}
private int IntAssignToInt()
{
int x = _Int;
return x;
}
private float FloatConvertToFloat()
{
float x = (float)_Float; //Additional OpCode
return x;
}
private float FloatAssignToFloat()
{
float x = _Float;
return x;
}
private double DoubleConvertToDouble()
{
double x = (double)_Double; //Additional OpCode
return x;
}
private double DoubleAssignToDouble()
{
double x = _Double;
return x;
}
private Object ObjectConvertToObject()
{
Object x = (Object)_Object;
return x;
}
private Object ObjectAssignToObject()
{
Object x = _Object;
return x;
}
Coresponding Il:
.method private hidebysig
instance int32 IntConvertToInt() cil managed
{
// Method begins at RVA 0x2052
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 ConversionTest.Program::_Int
IL_0006: ret
} // end of method Program::IntConvertToInt
.method private hidebysig
instance int32 IntAssignToInt() cil managed
{
// Method begins at RVA 0x2052
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld int32 ConversionTest.Program::_Int
IL_0006: ret
} // end of method Program::IntAssignToInt
.method private hidebysig
instance float32 FloatConvertToFloat() cil managed
{
// Method begins at RVA 0x205a
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld float32 ConversionTest.Program::_Float
IL_0006: conv.r4 //here
IL_0007: ret
} // end of method Program::FloatConvertToFloat
.method private hidebysig
instance float32 FloatAssignToFloat() cil managed
{
// Method begins at RVA 0x2063
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld float32 ConversionTest.Program::_Float
IL_0006: ret
} // end of method Program::FloatAssignToFloat
.method private hidebysig
instance float64 DoubleConvertToDouble() cil managed
{
// Method begins at RVA 0x206b
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld float64 ConversionTest.Program::_Double
IL_0006: conv.r8 //here
IL_0007: ret
} // end of method Program::DoubleConvertToDouble
.method private hidebysig
instance float64 DoubleAssignToDouble() cil managed
{
// Method begins at RVA 0x2074
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld float64 ConversionTest.Program::_Double
IL_0006: ret
} // end of method Program::DoubleAssignToDouble
.method private hidebysig
instance object ObjectConvertToObject() cil managed
{
// Method begins at RVA 0x207c
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld object ConversionTest.Program::_Object
IL_0006: ret
} // end of method Program::ObjectConvertToObject
.method private hidebysig
instance object ObjectAssignToObject() cil managed
{
// Method begins at RVA 0x207c
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldfld object ConversionTest.Program::_Object
IL_0006: ret
}
Почему Conv.R4/Conv.R8 ведет себя таким образом? Является ли этот код операции важным или может быть безопасно удалено/обрезано?
Пожалуйста, разместите объявление обо всех этих полях. –
@ LasseV.Karlsen Не аргумент 'ldfld' уже показывает объявленный тип поля? 'ldfld float32 ConversionTest.Program :: _ Float' указывает на загрузку' float32', а затем его вызов 'conv.r4'. – InBetween