那些年,我们应该读的书 《Effective_C#_中文版_改善C#程序的50种方法》第二章

来源:互联网 发布:java软件开发项目经验 编辑:程序博客网 时间:2024/06/05 06:56

第一章       .N资源管理

原则12:选择变量初始化而不是赋值语句

Thinking :

如果在一类中没有定义一个构造函数,那么系统会为这个类添加一个没有参数的默认构造函数。

这一节中还提到一个问题,不用给整型初始化一个0值、不用给一个类型初始化Null值,因为系统会为这个整型自动初始化个=0的值、类型自动初始化Null值,也就是说自己对整型初始化为0或是为类型初始化Null都是多余的。

以下的这段代码是错误的,因为会有2个ArrayList类被实例化。

publicclass MyClass{

 private ArrayList _coll = new ArrayList();

 MyClass()  {  }

 MyClass(int size)  {    _coll = new ArrayList(size); }

}

原则13:用静态构造函数初始化类的静态成员

Thinking :

以前有个同事问过我什么时候用静态构造函数,我当时一听就蒙了“静态构造函数”,这些年来还真没有用过,更没有听过。后来去查了查,才知道“静态构造函数”一般用在一个叫“单件”的模式中,也就是这个类一开始就实例化了,且只有一个,如果外部要得到这个类的实例,那就通过这个类的一个开放的接口去取。

这个“静态构造函数”还可以对静态变量赋值。

原则14:使用构造函数链

Thinking :

刚一看到这节的名字又蒙了,这是什么哦,又是第一次听到。

在看的过程中想到以前看过的一本书(那本书没有看完),那本书中提到过一个问题,程序员在写多个构造函数时一定要考虑到一个问题,也就是如果用户在使用你的这个类时,用户没有传有效的参数来构造类时,一定要能容错。那书中给出了一段代码(记不清了,自己编了一段),如下:

publicclass MyClass

{

 private ArrayList _coll;

 private string  _name;

 public MyClass()   {  }

 public MyClass(int initialCount)   {  }  

 public MyClass(int initialCount, string name) { MyValueJudge(initialCount,name) }

privatevoid MyValueJudge(int initialCount, string name){

if(name==null)MyClass(initialCount);

Else if (name==null && initialCount==null)MyClass();

Else MyClass();

}

}

原则15:使用using和try/finally来做资源清理

Thinking :

这一节在讲要使用using时你要先知道那个类的实例是否实现了IDisposable接口;在.Net框架里的1500多个类中,只有不到100个类实现了IDisposable接口。我常用的有SQL类与IO类。

如果是个常用的实例一般不用using;

Dispose()并不会从内存里把对象移走,对于让对象释放非托管资源来说是一个hook。这就是说你可能遇到这样的难题,就是释放一个还在使用的对象。不要释放一个在程序其它地方还在引用的对象。

无论使用using还是try/finally非托管的资源一定要记得清理。

原则16:垃圾最小化

Thinking :

我一看到这个名字就先想到了几点:少定一此不常用的变量或临时的变量、清理不用的dll、不要反复的实例化对象、非托管资源记得清理、常用的对象不要使用Using等等,这会只想到这些。

对于常用的对象要从局部提升到全局使用。

这一节中给出了一段,让我“受惊”的代码,因为我常用。

string msg= "Hello, ";

msg +=thisUser.Name;

msg +=". Today is ";

msg +=System.DateTime.Now.ToString();

+=方法在字符串类上会生成一个新的对象并返回它。

使用:

string msg= string.Format ("Hello, {0}. Today is {1}",

 thisUser.Name, DateTime.Now.ToString());

来解决这个好办法。

    对于更多的复杂的字符串操作,应该使用StringBuilter类,对于多次要写到文件中这个StringBuilter类更是首选。

原则17:装箱和拆箱的最小化

Thinking :

装箱就是值类型转换为object类型,拆箱相反:object转化为值类型

装箱(Boxing)和拆箱(Unboxing)这两个名词。.Net的类型分为两种,一种是值类型,另一种是引用类型。这两个类型的本质区别,值类型数据是分配在栈中,而引用类型数据分配在堆上。那么如果要把一个值类型数据放到堆上,就需要装箱操作;反之,把一个放在堆上的值类型数据取出来,则需要进行拆箱操作。

//Boxing   

int i =1;object obj = i;

//Unboxing

if( obj isint )int  j = (int) obj;

//或者

int  j = obj as int ;

if(j!=null){…}//Unboxing成功

else {…}//Unboxing失败

为什么要减少装箱和拆箱操作。

原因有两个,主要是关于效率:一个就是对于堆的操作效率比较低;另一个就是对于堆上分配的内存资源,需要GC来回收,从而降低程序效率。装箱是把一个值类型数据放置在一个无类型的引用对象上,从而使一个值类型在须要时可以当成引用类型来使用。拆箱则是额外的从“箱”上拷贝一份值类型数据。装箱与拆箱在性能上是“强盗”。

Console.WriteLine("Number list:{0}, {1}, {2}",1,2,3 );

//int型变为sting型才能打印,这里就要装箱。

//代码修改一下,就不用装箱了。

Console.WriteLine("Number list:{0}, {1}, {2}",

1.ToString(),2.ToString(),3.ToString());

原则18:实现标准的处理(Dispose)模式

Thinking :

这一小节我看的要懂不懂的,或可以说没有看懂。但是我知道释放非托管的资源是一定要Dispose的,这个一定要记住。然而有不少用户却忘了Dispose,那就要程序员帮他们完成这项工作了。这一小节好像是在讲这项工作,但我却不知道如何自动去Dispose。算了,以后用到了这点再来研究下一吧,虽然明天我可能就忘了这一点,我也不想再花时间去研究这一“标准”的Dispose了。可能是我在工作中用到这一点的时候太少了吧。

在第一章中提供了此书的下载地址~~~
原创粉丝点击