第一章 .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了。可能是我在工作中用到这一点的时候太少了吧。
在第一章中提供了此书的下载地址~~~