C#:初始化类变量

时间:2011-06-09 03:15:30

标签: c# .net constructor class-design

  

可能重复:
  C# member variable initialization; best practice?

这是初始化类变量的正确方法。 [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 = "";
     }
}

3 个答案:

答案 0 :(得分:5)

作为声明的一部分分配了默认值的实例变量将在构造函数运行之前分配此值,从外部看,1)和2)之间没有明显的行为差异,它主要是一个问题风格。

您还在方法2中引入了一个额外的InitializePerson()方法 - 如果您有多个构造函数,然后所有构造函数都可以使用相同的公共初始化方法(保持代码DRY),这将是有益的。

编辑以回复评论,请参阅MSDN

  

字段立即初始化   在对象的构造函数之前   实例被调用。如果是构造函数   分配一个字段的值,它会   覆盖字段期间给出的任何值   声明。

答案 1 :(得分: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 
}

答案 2 :(得分:0)

在第二种情况下,如果在mPersonName中分配之前尝试在构造函数中引用InitializePerson,则会得到一个空引用异常,因为String默认为NULL。 int默认值为0,因此没有问题。在第一种情况下,您不必担心在构造函数中使用它们的位置,因为您在类级别为声明赋值。否则,没有区别。