none
C# 类具有多个构造函数时,字段被初始的次数等于构造函数个数 ? RRS feed

  • 问题

  • class SomeType{
    private int m_x = 5;
    private string m_s = "Hi there";
    private double m_d = 3.14159;
    private byte m_b;

    public SomeType() { ... }
    public SomeType(int x){ ... }
    public SomeType(string s){ ...; m_d = 10; }
    }

    《CLR via C#》上说:“由于上面类有3个构造器,所以编译器共生成3次初始化 m_x,m_s,m_d的代码 —— 每个构造器一次.”

    问题:编译器为什么会生成 3次 初始化 m_x,m_s,m_d的代码(实例类时只会调用一个构造函数啊) ? 应该只初始化1次啊!

    2012年5月18日 8:19

答案

  • 因为编译器并不知道你究竟要调用那个构造函数,并且每个构造函数作用是不一样的。因此每一个构造函数自动会生成不同初始化各个变量的代码,不然你想想看——如果只生成一次,那么你万一调用了某个构造函数(它不初始化变量了),对不?何况你给出的代码就是给不同的实体变量赋值的,是不?呵呵……

    以下是IL:

    .class public auto ansi beforefieldinit SomeType
        extends [mscorlib]System.Object
    {
      
        .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
        {
            .maxstack 8
            L_0000: ldarg.0 
            L_0001: ldc.i4.5 
            L_0002: stfld int32 CSharp.ConsoleApplication7.SomeType::m_x
            L_0007: ldarg.0 
            L_0008: ldstr "Hi there"
            L_000d: stfld string CSharp.ConsoleApplication7.SomeType::m_s
            L_0012: ldarg.0 
            L_0013: ldc.r8 3.14159
            L_001c: stfld float64 CSharp.ConsoleApplication7.SomeType::m_d
            L_0021: ldarg.0 
            L_0022: call instance void [mscorlib]System.Object::.ctor()
            L_0027: ret 
        }
    
        .method public hidebysig specialname rtspecialname instance void .ctor(int32 x) cil managed
        {
            .maxstack 8
            L_0000: ldarg.0 
            L_0001: ldc.i4.5 
            L_0002: stfld int32 CSharp.ConsoleApplication7.SomeType::m_x
            L_0007: ldarg.0 
            L_0008: ldstr "Hi there"
            L_000d: stfld string CSharp.ConsoleApplication7.SomeType::m_s
            L_0012: ldarg.0 
            L_0013: ldc.r8 3.14159
            L_001c: stfld float64 CSharp.ConsoleApplication7.SomeType::m_d
            L_0021: ldarg.0 
            L_0022: call instance void [mscorlib]System.Object::.ctor()
            L_0027: ret 
        }
      
        .method public hidebysig specialname rtspecialname instance void .ctor(string s) cil managed
        {
            .maxstack 8
            L_0000: ldarg.0 
            L_0001: ldc.i4.5 
            L_0002: stfld int32 CSharp.ConsoleApplication7.SomeType::m_x
            L_0007: ldarg.0 
            L_0008: ldstr "Hi there"
            L_000d: stfld string CSharp.ConsoleApplication7.SomeType::m_s
            L_0012: ldarg.0 
            L_0013: ldc.r8 3.14159
            L_001c: stfld float64 CSharp.ConsoleApplication7.SomeType::m_d
            L_0021: ldarg.0 
            L_0022: call instance void [mscorlib]System.Object::.ctor()
            L_0027: ret 
        }
    }

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    • 已标记为答案 良牙 2012年5月19日 2:48
    2012年5月18日 10:42
    版主