What's wrong with this code ?

这个有意思的问题出自Eric Gu的Blog。代码如下:

public void TransmitResponse(ArrayList responses,
                             StreamWriter streamWriter)
{
   foreach (DataResponse response in responses)
   {
      NetworkResponse networkResponse = response.GetNetwork();
      networkResponse.Send(streamWriter);
   }
   GC.Collect();      // clean up temporary objects
}


这段代码问题何在?

原Blog Entry的众多回复非常有意思。首先,有人指出,代码没有关闭NetworkResponse对象和StreamWriter对象,应该在代码中加上“using”来保证正确调用这些对象的Dispose()方法。但是,随即有人指出,在这个方法中调用这些对象的Dispose(),是不正确的。

首先,作为参数的DataResponse集合和StreamWriter对象,根本不能假定它们“应该”在这个方法内部被关闭,也许在调用这个方法之后,其他地方仍然要使用它们。而在循环中通过GetNetwork()方法得到的临时NetworkResponse对象,很难看出GetNetwork()方法是否是创建一个新的NetworkResponse对象抑或只是返回一个已有的对象(还有人指出,如果是创建一个新的对象,那个方法名称应该是CreateNetwork(),而不是GetNetwork()),所以贸然调用它的Dispose()也是不可取的。

最后讨论的结果,这段代码的问题主要是:1、代码中未检测各个相关的对象是否为null,或者ArrayList中的对象是否类型正确;2、调用GC.Collect()毫无理由。

原Blog Entry的众多回复所统一的意见:只有一个方法亲自创建了一个新的对象实例,才有义务调用这个实例的Dispose()。

呵呵,我想到一个典型的“反例”,那就是ADO.NET中DataReader的使用,它的使用者在某些情况下,有义务调用它的Close()方法。当然,作为开发人员,可以利用各种模式来“修正”这个“反例”。比如,这篇文章所介绍的使用Delegate来将DataReader的Dispose责任回收到创建DataReader的地方。

你可能感兴趣的:(code)