2011-06-09 243 views
4

可能重复:
C# member variable initialization; best practice?C#:初始化类变量

这是初始化类变量的正确方法。 [1]和[2]之间的区别是什么?

//[1] 
public class Person 
{ 
    private int mPersonID = 0; 
    private string mPersonName = ""; 
} 

OR

//[2] 
public class Person 
{ 
    private int mPersonID = 0; 
    private string mPersonName = ""; 

    public Person() 
    { 
     InitializePerson(); 
    } 

    private void InitializePerson() 
    { 
      mPersonID = 0; 
      mPersonName = ""; 
    } 
} 
+0

还有类似的问题在这里:http://stackoverflow.com/questions/298183/c-member-variable-initialization-best-practice – RandomWebGuy 2011-06-09 03:21:23

回答

5

实例变量从外面看,1)和2)之间没有明显的行为差异,这主要是风格问题。

你也在你的方法中引入了一个额外的InitializePerson()方法2) - 如果你有多个构造函数,那么所有可以使用相同的通用初始化方法(这会使代码保持干燥)。

编辑回应评论,看到MSDN

字段是构造函数 实例被称为对象之前立即 初始化。如果构造函数 指定了一个字段的值,它将会覆盖 声明期间给出的任何值 。

+0

如何在构造函数之前分配字段? – 2011-06-09 03:25:06

+0

@Alex:这就是它的工作原理,你也可以查看http://msdn.microsoft.com/en-us/library/ms173118%28v=vs.80%29.aspx以获得参考 – BrokenGlass 2011-06-09 03:27:06

+0

我希望写这篇文章的人这解释了如何在构造函数之前调用代码。看看我的答案,代码肯定在构造函数内部。 – 2011-06-09 03:31:09

2

在这两种情况下,将产生IL会看起来几乎是相同的。说'差不多',因为你在第二种方法中引入了额外的方法。如果你只是把它放到构造函数中,而不是相同的IL代码。

所以最好使用方法#1,因为它代码少。

此外,您不需要指定默认值(0代表int,null代表参考类型)。

这两个例子产生相同的IL:

public class Test 
{ 
    private string test1 = ""; 
} 

public class Test 
{ 
    private string test1; 

    public public Test() 
    { 
     test1 = ""; 
    } 
} 

IL:被分配一个默认值作为其声明的一部分就会获得这个值分配权前的构造是

.method public hidebysig specialname rtspecialname instance void .ctor() cil managed 
{ 
    .maxstack 8 
    L_0000: ldarg.0 
    L_0001: ldstr "" 
    L_0006: stfld string ConsoleApplication1.Test::test1 
    L_000b: ldarg.0 
    L_000c: call instance void [mscorlib]System.Object::.ctor() 
    L_0011: nop 
    L_0012: ret 
} 
+0

所以我需要分配字符串“”,对不对? – devnull 2011-06-09 03:18:55

+0

是的,如果你想它是相等的“”,这是不一样的空 – 2011-06-09 03:20:54

+0

是否有一些具体的原因,你想默认一个字符串空字符串而不是null?如果不是,那么不,你不需要。 – Khepri 2011-06-09 03:21:19

0

在第二种情况,如果试图在构造函数中引用mPersonNameInitializePerson分配给它之前,你会得到一个空引用异常,因为字符串默认为NULL。 int默认值为0,所以这里没有问题。在第一种情况下,您不必担心在构造函数中使用它们的位置,因为您在类级别声明了值。否则,没有区别。