Effective C# 读书笔记(1)
1.尽可能的使用属性(property),而不是数据成员(field)
(1).net对属性的支持大于对数据成员的支持。如对属性进行数据绑定。
(2)数据安全性检测
在对数据检测时,如果发现数据不满足条件,最好抛出异常的形式来解决,不要设置默认值。
(3)线程同步
(4)属性可以是抽象的,而数据成员不能是抽象的。
(5)属性可以以接口的形式表现,而接口里不能定义数据成员。
(6)基于属性的索引。
2.为常量选择readonly而不是const
对于常量,C#分为运行时常量和编译时常量。
用关键字readonly来声明一个运行时常量,编译时常量用关键字const声明的。
编译时常量与运行时常量不同之处表现在如何对他们的访问上。一个编译时常量会目标代码中的值直接取代。
if(myDateTime.Year == _Millennium)
会与下面写的代码编译成完全相同的IL代码:
if(myDateTime.Year == 2000)
运行时常量的值是在运行时确定的。当你引用一个只读常量时IL会为你引用一个运行时常量的变量,而不是直接使用此值。
编译时常只能是基本类型,枚举或者是字符串。不能用new运算符初始化一个编译时常量,即使这个数据类型是值类型。
private const DateTime _classCreation = new DateTime(2000,1,1,0,0,0);
运行时常量可以是任何类型的数据。而且你必须在构造函数里对他们初始化,或者你可以用任何一个初始化函数来完成。
你可以把每一个实例的常量指定为只读的,从而为每一个类的实例存放不同的值。
只读数据最重要的区别是他们在运行时才确定值。
3.选择is或者as操作符而不是做强制类型转换
正确的选择是用as运算符进行类型转换。因为比起盲目的强制转换它更安全,而且在运行时效率更高。用as和is运算符进行转换时,并不是对所有的用户定义的类型都能完成的。它们只在运行时类型和目标类型匹配的时候,转换才能成功。它们决不会构造一个新的对象来满足转化要求。
当你用强制类型转换时,就得用一个try/catch结构来捕获转换null时的异常。用as进行转换的时就,就只用简单的检测一下转化后的实例不为null就行了。
4.用条件属性而不是#if
使用#if/#endif可以生成debug和release两个版本。C#就提供了条件属性(Conditional attribute)来识别哪些方法可以根据环境设置来判断是否应该被调用。
[ Conditional( "DEBUG" ) ]
private void CheckState( )
{
// same code as above
}
Conditional属性会告诉C#编译器,这个方法只在编译环境变量DEBUG有定义时才被调用。
5.始终提供ToString()
6.区别值类型和引用类型