Effective C中文版改善C程序的50种方法 读后小感

为你的常量选择readonly而不是const:
Const:编译时常量,运行快,可能产生错误(对性能要求苛刻,且随程序运行时间过去,值不会发生改变)。编译时常量仅限于数字和字符串。
ReadOnly:运行时常量,可以是任何类型的数据,在运行时才确定值。

选择is或者as操作符而不是做强制类型转换:
强制转换的方法为了检测转换是否把一个null的对象进行强制转换,而不得不添加一个捕获异常的结构。null可以被转换为任意的引用类型,但as操作符就算是转化一个null的引用时,也会(安全的)返回一个null。所以当你用强制类型转换时,就得用一个try/catch结构来捕获转换null时的异常。用as进行转换的时就,就只用简单的检测一下转化后的实例不为null就行了。
例:

Object o = Factory.GetObject();
Mytype t = o as Mytype;
  if(t!=null){} //work with it,it is a Mytype
  else {} // report the failure

 对一个用户定义类型的对象,转换操作只是在编译时,而不是在运行时。

object o = Factory.GetValue();
int i = o as int;

 当o不为int时,返回null,而int是值类型,不为null,即这样编译不通过。可换为:

object o = Factory.GetValue();
int i =0;
if(o is int)
  i=(int)o;

 注:is和as一样,都是类型安全转换,它们在任何时候都不会在转换时发生异常,因此可以现用is来安全的判断一下数据类型。与as不同的时候,is只是做类型检测并返回逻辑值,不做转换。
foreach的使用:

public void UseCollection( IEnumerable theCollection )
{
  foreach ( MyType t in theCollection )
    t.DoStuff( );
}

等价于:

public void UseCollection( IEnumerable theCollection )
{
  IEnumerator it = theCollection.GetEnumerator( );
  while ( it.MoveNext( ) )
  {
    MyType t = ( MyType ) it.Current;
    t.DoStuff( );
  }
}

 确保0对于值类型数据是有效的:
决不要创建一个不包括0在内的枚举类型,如果可能,选择把0作为一个最好的默认。
 明白GetHashCode()的缺陷:
GetHashCode()具有很特殊的要求:相等的对象必须产生相等的散列值,并且散列值必须是对象不变的,并且是均衡的高效分布。所有这些只有对恒定类型才能满足。对于其它类型,就交给默认的行为吧。
 选择foreach循环:

int [] foo = new int[100];
  
// Loop 1:
foreach ( int i in foo)
  Console.WriteLine( i.ToString( ));
  
// Loop 2:
for ( int index = 0;  index < foo.Length;  index++ )
  Console.WriteLine( foo[index].ToString( ));
  
// Loop 3:
int len = foo.Length;
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 ];
  
// elsewhere in code:
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 )
  sq.PaintSquare( );

(注:它隐藏了数组的行与列的逻辑关系。循环是以行优先的,如果你要的不是这个顺序,那么这种循环并不好。)

  任何时候你在使用一个有Dispose()方法的类型时,你就有责任来调用Dispose()方法来释放资源。
  当你把对象分配到using语句内时,C#的编译器就把这些对象放倒一个try/finally块内

SqlConnection myConnection = null;
  
// Example Using clause:
using ( myConnection = new SqlConnection( connString ))
{
  myConnection.Open();
}

编译后等同于:

// example Try / Catch block:
try {
  myConnection = new SqlConnection( connString );
  myConnection.Open();
}
finally {
  myConnection.Dispose( );
}

每一个using语句生成了一个新的嵌套的try/finally块。我发现这是很糟糕的结构,所以,如果是遇到多个实现了IDisposable接口的对象时,还是推荐写try/finally块。
  String和StringBuild的区别:
在于,一个是累加,一个是添加。
String每次重新生成一个字符串覆盖之前的,StringBuild每次往之中添加一个字符串。

转载于:https://www.cnblogs.com/zhutingsh/archive/2011/08/24/2152290.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值