C#:常量的类型转换是否在运行时发生?

时间:2013-04-24 12:37:04

标签: c# casting enums runtime compile-time

首先,这个问题是不是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;

在哪些情况下,类型转换是在运行时发生的?我现在觉得有点迷恋我的节目表现,并且想知道这是否会有任何(无论多小)影响。

2 个答案:

答案 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 
}

如您所见,没有发生运行时强制转换。发布或调试版本也是如此。