首先,这个问题是不是this question的重复。除了标题之外,它绝对没有任何共同之处。
现在...
在C#中,请考虑以下情况:
int i = (int)10.0;
const double D = 10.0;
float f = (float)d;
enum Foo : int
{
FIRST_ITEM = 0
}
int i = (int)Foo.FIRST_ITEM;
在哪些情况下,类型转换是在运行时发生的?我现在觉得有点迷恋我的节目表现,并且想知道这是否会有任何(无论多小)影响。
答案 0 :(得分:4)
简而言之,Linqpad静态地执行了很多操作,这意味着当使用带有优化标志的ms或mono编译器进行编译时,它们至少应该静态地执行。
使用Linqpad时,我会使用以下C#代码:
void Main()
{
int i = (int)10.0;
const double D = 10.0;
float f = (float)D;
int h = (int) Foo.Bar;
}
public enum Foo : int {
Bar = 0
}
我得到以下IL:
IL_0001: ldc.i4.s 0A // load int8 0A (ie 10 dec)
IL_0003: stloc.0 // assign i
IL_0004: ldc.r4 00 00 20 41 // FLOAT! not double
IL_0009: stloc.1 // assign f
IL_000A: ldc.i4.0 // load int32 0 (due to Foo : int(32))
IL_000B: stloc.2 // assign h
答案 1 :(得分:2)
来自常量的强制转换是在编译时完成的。
为了证明这一点,您可以使用.Net Reflector检查生成的代码。
例如,此代码:
static void Main()
{
int i = (int) 10.5;
const double d = 10.0;
float f = (float)d;
Console.WriteLine(i);
Console.WriteLine(f);
}
产地:
private static void Main()
{
int i = 0xa;
float f = 10f;
Console.WriteLine(i);
Console.WriteLine(f);
}
或作为IL:
.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 1
.locals init (
[0] int32 i,
[1] float32 f)
L_0000: ldc.i4.s 0xa
L_0002: stloc.0
L_0003: ldc.r4 10
L_0008: stloc.1
L_0009: ldloc.0
L_000a: call void [mscorlib]System.Console::WriteLine(int32)
L_000f: ldloc.1
L_0010: call void [mscorlib]System.Console::WriteLine(float32)
L_0015: ret
}
如您所见,没有发生运行时强制转换。发布或调试版本也是如此。