为你的常量选择readonly而不是const:
Const:编译时常量,运行快,可能产生错误(对性能要求苛刻,且随程序运行时间过去,值不会发生改变)。编译时常量仅限于数字和字符串。
ReadOnly:运行时常量,可以是任何类型的数据,在运行时才确定值。
选择is或者as操作符而不是做强制类型转换:
强制转换的方法为了检测转换是否把一个null的对象进行强制转换,而不得不添加一个捕获异常的结构。null可以被转换为任意的引用类型,但as操作符就算是转化一个null的引用时,也会(安全的)返回一个null。所以当你用强制类型转换时,就得用一个try/catch结构来捕获转换null时的异常。用as进行转换的时就,就只用简单的检测一下转化后的实例不为null就行了。
例:
Object o = Factory.GetObject(); |
对一个用户定义类型的对象,转换操作只是在编译时,而不是在运行时。
object o = Factory.GetValue(); |
当o不为int时,返回null,而int是值类型,不为null,即这样编译不通过。可换为:
object o = Factory.GetValue(); |
注:is和as一样,都是类型安全转换,它们在任何时候都不会在转换时发生异常,因此可以现用is来安全的判断一下数据类型。与as不同的时候,is只是做类型检测并返回逻辑值,不做转换。
foreach的使用:
public void UseCollection( IEnumerable theCollection ) |
foreach ( MyType t in theCollection ) |
等价于:
public void UseCollection( IEnumerable theCollection ) |
IEnumerator it = theCollection.GetEnumerator( ); |
MyType t = ( MyType ) it.Current; |
确保0对于值类型数据是有效的:
决不要创建一个不包括0在内的枚举类型,如果可能,选择把0作为一个最好的默认。
明白GetHashCode()的缺陷:
GetHashCode()具有很特殊的要求:相等的对象必须产生相等的散列值,并且散列值必须是对象不变的,并且是均衡的高效分布。所有这些只有对恒定类型才能满足。对于其它类型,就交给默认的行为吧。
选择foreach循环:
int [] foo = new int [100]; |
Console.WriteLine( i.ToString( )); |
for ( int index = 0; index < foo.Length; index++ ) |
Console.WriteLine( foo[index].ToString( )); |
for ( int index = 0; index < len; index++ ) |
Console.WriteLine( foo[index].ToString( )); |
对于当前的C#编译器(版本1.1或者更高)而言,循环1是最好的。起码它的输入要少些,这会使你的个人开发效率提提升。(1.0的C#编译器对循环1而言要慢很多,所以对于那个版本循环2是最好的。) 循环3,大多数C或者C++程序员会认为它是最有效的,但它是最糟糕的。因为在循环外部取出了变量Length的值,从而阻碍了JIT编译器将边界检测从循环中移出。
对于多维数组,foreach给了你同样的好处。假设你正在创建一个棋盘。你将会这样写两段代码:
private Square[,] _theBoard = new Square[ 8, 8 ]; |
for ( int i = 0; i < _theBoard.GetLength( 0 ); i++ ) |
for ( int j = 0; j < _theBoard.GetLength( 1 ); j++ ) |
_theBoard[ i, j ].PaintSquare( ); |
取而代之的是,你可以这样简单的画这个棋盘:
foreach ( Square sq in _theBoard ) |
(注:它隐藏了数组的行与列的逻辑关系。循环是以行优先的,如果你要的不是这个顺序,那么这种循环并不好。)
任何时候你在使用一个有Dispose()方法的类型时,你就有责任来调用Dispose()方法来释放资源。
当你把对象分配到using语句内时,C#的编译器就把这些对象放倒一个try/finally块内
SqlConnection myConnection = null ; |
using ( myConnection = new SqlConnection( connString )) |
编译后等同于:
myConnection = new SqlConnection( connString ); |
每一个using语句生成了一个新的嵌套的try/finally块。我发现这是很糟糕的结构,所以,如果是遇到多个实现了IDisposable接口的对象时,还是推荐写try/finally块。
String和StringBuild的区别:
在于,一个是累加,一个是添加。
String每次重新生成一个字符串覆盖之前的,StringBuild每次往之中添加一个字符串。