2010-02-01 70 views
2

我一直都在想这个。在C#中,具有默认值的实例变量何时被设置 - 构造函数之前还是之后?C#何时使用默认值设置实例变量?

对于这个代码:

public class Foo 
{ 
    public int bar=1; 
    public Foo() 
    { 
    bar = 2; 
    } 
} 
... 
Console.WriteLine(new Foo().bar); 

将它输出1或2?

+5

这是非常简单的答案,你自己可以有tried.you应该问为什么happpens。 – Ravisha 2010-02-01 02:54:40

回答

4

构造期间的实例将首先遍历所有声明,然后继续进入构造函数本身。

因此,巴= 1将巴= 2,但最终的结果之前执行仍将是巴= 2

+0

谢谢队友!快速回答。那是我怀疑的。 – Chris 2010-02-01 02:55:27

1

它将返回2,您在构造函数修改后访问该属性。

0

你为什么不考呢?

当实例化一个类对象时,你基本上创建了一个类的实例,然后运行构造函数。因此,它应该输出2

+1

我可能可以测试它......但我想这里,我可能会得出一些推论,为什么它是这样的。 – Chris 2010-02-01 02:55:53

+1

我并不是很喜欢“自己试试”或“自己google自己”的答案,这些答案似乎现在已经变得非常普遍了。虽然我同意人们应该努力搞清楚这些事情自己先问一个问题之前,这是非常offputting,如果他们认为他们会得到这样一个典型的“RTFM!你输”的评论人可能会害怕问问题在各种开源论坛中经常发生。 – 2010-02-01 03:04:14

+0

如果你读的问题,我的答案,你会看到我的回答有“幕后黑手为什么它是事情是这样的一些推理”。当有人提出一段代码后,会问“它会输出1还是2?”,我不禁回答我的方式。有时好的答案需要很好的问题。 SO问题不应该用作C#编译器。 – Omar 2010-02-01 05:35:45

0

底层字节码在调用构造函数之前没有任何特殊的能力来初始化这些值。 C#编译器负责订货,这是发出作为方法的字节码称为.ctor的类型:

如果构造函数没有指定this(...)作为链构造,这意味着它要么指定base(...)还是什么都没有,然后它:

  1. 设置具有初始值设定项的所有字段的值。
  2. 调用基类的构造函数。如果没有指定具体的,它会调用默认的。
  3. 运行您在构造函数中键入的代码。

如果构造函数指定this(...)作为链接构造函数,顺序稍有不同,因为链接的构造函数将处理字段的初始化。

  1. 调用链式构造函数,这是您明确用: this(...)表示的构造函数。
  2. 运行您在构造函数中键入的代码。
1

成员实例化首先在构造函数中添加。如果检查出是使用反射实际上产生的IL代码,这是编译器做什么用:

.class auto ansi nested public beforefieldinit Foo 
    extends [mscorlib]System.Object 
{ 
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed 
    { 
    .maxstack 8 
    L_0000: ldarg.0 
    L_0001: ldc.i4.1 
    L_0002: stfld int32 Test.Program/Foo::bar 
    L_0007: ldarg.0 
    L_0008: call instance void [mscorlib]System.Object::.ctor() 
    L_000d: nop 
    L_000e: nop 
    L_000f: ldarg.0 
    L_0010: ldc.i4.2 
    L_0011: stfld int32 Test.Program/Foo::bar 
    L_0016: nop 
    L_0017: ret 
    } 

    .field public int32 bar 

} 

所以,成员实例首先被放置在构造函数中,然后调用基础的构造类型,然后出现在构造函数中的代码。

0

如果这种情况没有发生,它可以创造一些非常混乱和不直观的情况。就像某些东西在你的构造中根据栏的初始值的特定的方式行事,那就不知道,如果它已被初始化(或更糟的是,酒吧是一个用户定义的类,而不是一个int。是不是null,因为构造函数该类希望它是吗?还是有它只是没有被初始化?) 它有助于想到构造的,你班的诞生过程,就像一个婴儿居然弹出它的木乃伊,并初始化作为成长点子宫。 前置条件,如初始化在给定的 - 你不会看到天生没有手臂婴儿,然后突然间,他们后来又出现了一个小时你会吗?