《Effective C#》Item 14:使用构造函数初始化语句

在写程序的时候,往往会出现为一个类型提供不同场景的构造函数,可能大多构造函数比较相似,而C#中又不允许缺省参数,因此构造函数的编写无疑是一个重复工作。但是使用Copy和Paste来完成构造函数的编写,有时候很难达到统一,尤其是当成员发生变化的时候。因此比较常见的替换方法就是为构造函数提供一个统一的成员函数来完成初始化工作。

例如:

public class MyClass

{

private int _Age;

private string _Name;

public MyClass( string Name)

{

InitMember( Name, 20 );

}

public MyClass( string Name, int Age )

{

InitMember( Name, Age );

}

/// <summary>

/// Init class members

/// </summary>

/// <param name="Name"></param>

/// <param name="Age"></param>

private void InitMember( string Name, int Age )

{

_Age = Age;

_Name = Name;

}

}

不过,在C#中提供了更为简明的方法,就是在构造函数初始化语句中调用另一构造函数,那么上面的形式可以改写为如下这样。

public class MyClass

{

private int _Age;

private string _Name;

public MyClass( string Name):this( Name, 20 )

{

}

public MyClass( string Name, int Age )

{

_Age = Age;

_Name = Name;

}

}

对于这两者来说,执行效率没有太大差别,但从代码质量而言,后者要好很多,而且会使代码看起来更清晰。

其次,对于基类的调用。由于成员函数不能调用基类的构造函数,所以对于第一种编写就比较困难,后者就简单多了。

例如:

public class MyClass:BaseClass

{

private int _Age;

private string _Name;

public MyClass( string Name):this( Name, 20 )

{

}

public MyClass( string Name, int Age ):base( Name, Age )

{

_Age = Age;

_Name = Name;

}

}

这里要提的一点就是构造函数初始化语句,对于“this”或者“base”之类的调用只能有一个,不能并存。

最后,就是对于readonly常量的初始化,由于readonly常量只能通过成员初始化语句或者在构造函数中被修改,因此在成员函数中无法修改readonly常量,这也是构造函数初始化语句要比成员函数好的重要一个因素。

有了上面的说明,对于两者的对比,可以形成如下这个简单的对比表。

效率

代码结构

基类调用

静态成员初始化

构造函数初始化语句

一样

简明清晰

容易

可以

成员函数

比较清晰

比较麻烦

不能

(注:这里不提倡Copy/Paste方法来重复编写构造函数)