《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 ,如需转载请自行联系原作者
相关文章
|
Web App开发 C# Windows
一款.NET开源的Windows资源管理器标签页工具
一款.NET开源的Windows资源管理器标签页工具
371 5
《More Effective C# 》读书笔记 第一章
《More Effective C# 》读书笔记 第一章
276 0
|
安全 程序员 C++
读书笔记 effective c++ Item 3 在任何可能的时候使用 const
Const可以修饰什么?   Const 关键字是万能的,在类外部,你可以用它修饰全局的或者命名空间范围内的常量,也可以用它来修饰文件,函数和块作用域的静态常量。在类内部,你可以使用它来声明静态或者非静态的数据成员。
1121 0
|
C++ 安全 C#
读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数
1.关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样。如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为这是c++同它们不一样的地方。
1106 0
|
安全 C++ Python
读书笔记 effective c++ Item 11 在operator=中处理自我赋值
1.自我赋值是如何发生的 当一个对象委派给自己的时候,自我赋值就会发生: 1 class Widget { ... }; 2 3 Widget w; 4 5 ... 6 7 w = w; // assignment to self、 这看上去是愚蠢的,但这是合法的,所以请放心,客户端是可以这么做的。
1212 0
|
C++ 容器
读书笔记 effective c++ Item 13 用对象来管理资源
1.不要手动释放从函数返回的堆资源 假设你正在处理一个模拟Investment的程序库,不同的Investmetn类型从Investment基类继承而来, 1 class Investment { .
1218 0
|
C++
读书笔记 effective c++ Item 14 对资源管理类的拷贝行为要谨慎
1. 自己实现一个资源管理类  Item 13中介绍了 “资源获取之时也是初始化之时(RAII)”的概念,这个概念被当作资源管理类的“脊柱“,也描述了auto_ptr和tr1::shared_ptr是如何用堆资源来表现这个概念的。
1263 0
|
C++
读书笔记 effective c++ Item 18 使接口容易被正确使用,不容易被误用
1. 什么样的接口才是好的接口 C++中充斥着接口:函数接口,类接口,模板接口。每个接口都是客户同你的代码进行交互的一种方法。假设你正在面对的是一些“讲道理”的人员,这些客户尝试把工作做好,他们希望能够正确使用你的接口。
1136 0
|
C++
读书笔记 effective c++ Item 21 当你必须返回一个对象的时候,不要尝试返回引用
1. 问题的提出:要求函数返回对象时,可以返回引用么? 一旦程序员理解了按值传递有可能存在效率问题之后(Item 20),许多人都成了十字军战士,决心清除所有隐藏的按值传递所引起的开销。对纯净的按引用传递(不需要额外的构造或者析构)的追求丝毫没有懈怠,但他们的始终如一会产生致命的错误:它们开始传递指向并不存在的对象的引用。
1164 0
|
自然语言处理 数据安全/隐私保护 C++
读书笔记 effective c++ Item 22 将数据成员声明成private
我们首先看一下为什么数据成员不应该是public的,然后我们将会看到应用在public数据成员上的论证同样适用于protected成员。最后够得出结论:数据成员应该是private的。 1. 为什么数据成员不能是public的? 为什么数据成员不能够是public的? 2.1 一致性 让我们从句法的一致性开始(Item 18)。
1091 0

热门文章

最新文章