《Effective C#》读书笔记——条目12:推荐使用成员初始化器而不是赋值语句<.NET资源管理>

简介:

 一般情况下,一个类都会有多个构造函数。随着时间的推移,成员变量、构造函数不断增加。为了处理这种情况最方便的办法就是:在声明变量的时候进行初始化,而不是在每个构造函数中进行。无论是类成员(静态变量)合适实例变量,我们都应该充分利用初始化器的语法。

  C#编程在,一般在声明一个变量的同时我们会对其进行初始化:

1     class Employee
2     {
3         private List<Employee> empList = new List<Employee>();
4     }

不论我们为Employee类添加了多少个构造函数,empList变量都能够被正确的初始化,这是因为:

编译器会在所有的构造函数(包括默认构造函数)的最开始位置生成代码来为所以的实例成员变量定义初始化器(进行初始化);所以我们不需要再构造函数中为每一个定义的成员变量添加初始化代码——直接在声明的时候初始化即可。

  初始化器可以看做是构造函数中初始化语句的另一种表示。初始化器生成的代码会插入到构造函数代码前面执行。初始化器将在为类型执行调用基类构造函数之前执行,其顺序与类成员变量声明的顺序一样。

  C#的初始化器语法是一种最简单的、能够避免类型中存在未初始化变量的解决办法。但是在下面的三种情况下应该避免使用初始化器:

1.初始化对象为0或null时

   因为系统默认的初始化会将会在所有代码执行前把一切都设置成0或者null(值类型和引用类型)。而且这一步的操作是位于很底层的实现,我们也可以直接将对象赋值设置为0或null,但是显然这是多余的。

 

2.对同一个变量执行不同的初始化方式

   使用初始化语句的一个前提是:所有得构造函数都将为该变量设置同样的值。我们看下面的示例代码:

复制代码
 1     class Employee
 2     {
 3         //声明变量的同时进行初始化
 4         private List<Employee> empList = new List<Employee>();
 5 
 6         public Employee()
 7         {
 8         }
 9 
10         public Employee(int size)
11         {
12             empList = new List<Employee>(size);
13         }
14     }
复制代码

 

在上面的代码中,当我们调用第二个构造函数创建初始化指定大小的泛型集合时 ,实际上时创建了两个List<Employee>。第一个创建后马上变成了垃圾——这是由于初始化器将在所有构造函数之前执行。编译器生成的代码类似于下面的这段代码:

复制代码
 1     class Employee
 2     {
 3         //声明变量
 4         private List<Employee> empList;
 5 
 6         public Employee()
 7         {
 8               empList = new List<Employee>();
 9         }
10 
11         public Employee(int size)
12         {
13             empList = new List<Employee>();
14             empList = new List<Employee>(size);
15         }
16     }
复制代码

 我们可以看到这样做会影响程序的效率,创建了不必要的对象,所以如果需要在不同的构造函数中执行不同的初始化方式时正确的做法应该是不适用初始化器,而是先声明变量,然后在构造函数中进行成员变量的初始化,如下:

复制代码
 1      class Employee
 2      {
 3          //声明变量
 4          private List<Employee> empList;
 5  
 6          public Employee()
 7          {
 8                empList = new List<Employee>();
 9          }
10  
11          public Employee(int size)
12          {
13              empList = new List<Employee>(size);
14          }
15      }
复制代码

 

3.需要进行异常处理

   初始化器无法被try语句包裹。所以对象初始化器执行的过程中发生异常都会被传递到对象之外。如果在初始化对象的时候可能会抛出异常时我们应该将这部分代码放到构造函数中,对其进行异常处理。这样才能够实现必要的恢复性代码,以创建类型实例并以更友好的方式处理异常。

 

小节:

  成员初始化器是保证类型中成员变量都被初始化的最简单方法——在声明变量时就对其进行初始化,无论调用的是那个构造函数,初始化器都将会在所有构造函数之前执行。这种语法也避免了在添加新的构造函数时遗漏掉重要的初始化代码。所以,如果对于所有的构造函数某个成员变量的初始化值是一样的,那么就应该尽量使用初始化器语法。

 

本文转自gyzhao博客园博客,原文链接:http://www.cnblogs.com/IPrograming/archive/2012/11/06/Effective_CSharp_12.html ,如需转载请自行联系原作者
相关文章
|
3月前
|
C# 开发者
C# 9.0中的模块初始化器:程序启动的新控制点
【1月更文挑战第14天】本文介绍了C# 9.0中引入的新特性——模块初始化器(Module initializers)。模块初始化器允许开发者在程序集加载时执行特定代码,为类型初始化提供了更细粒度的控制。文章详细阐述了模块初始化器的语法、用途以及与传统类型初始化器的区别,并通过示例代码展示了如何在实际项目中应用这一新特性。
|
1月前
|
自然语言处理 C# 数据安全/隐私保护
50.c#:string类初始化
50.c#:string类初始化
12 1
|
3月前
|
存储 C# 容器
掌握 C# 变量:在代码中声明、初始化和使用不同类型的综合指南
变量是用于存储数据值的容器。 在 C# 中,有不同类型的变量(用不同的关键字定义),例如: int - 存储整数(没有小数点的整数),如 123 或 -123 double - 存储浮点数,有小数点,如 19.99 或 -19.99 char - 存储单个字符,如 'a' 或 'B'。Char 值用单引号括起来 string - 存储文本,如 "Hello World"。String 值用双引号括起来 bool - 存储具有两个状态的值:true 或 false
37 2
|
9月前
|
C#
C#中声明、初始化和实例化
C#中声明、初始化和实例化