0

首先,这个问题不是这个问题的重复。除了标题之外,它完全没有共同点。

现在...

在 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;

在哪种情况下,类型转换会在运行时发生?我现在有点沉迷于我的程序的性能,并且想知道这是否会产生任何(无论多么小)的影响。

4

2 回答 2

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
于 2013-04-24T12:55:15.413 回答
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 
}

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

于 2013-04-24T12:55:06.693 回答