Tracer(Constants.TraceLog)){MyResponseabc=newMyResponse();//一些代码返回abc;当我运行代码分析时,我收到CA2000警告Microsoft.Reliability代码应重写为:publicMyResponseMyMethod(stringarg){MyResponseabc=newMyResponse();using(TracermyTracer=newTracer(Constants.TraceLog)){//一些代码}returnabc;或者可以吗?编辑报告警告的行是:MyResponseabc=newMyResponse();MyResponse是一个标准数据集。完整的错误消息是:WARNING150CA2000:Microsoft.Reliability:Inmethod'xxxxx(Guid,Guid)',object'MyResponse'wasnotplacedalongallexceptionpaths。在对象“MyResponse”的所有引用超出范围之前调用System.IDisposable.Dispose。您的重写不会修复CA2000警告,因为问题不是Tracer对象,而是MyResponse对象。文档说明:以下是using语句不足以保护IDisposable对象的一些情况,可能会导致CA2000发生。返回一次性对象需要在using块之外的try/finally块中构造对象。要修复警告而不弄乱异常的堆栈跟踪(publicMyResponseMyMethod(stringarg){MyResponsetmpResponse=null;MyResponseresponse=null;try{tmpResponse=newMyResponse();using(TracermyTracer=newTracer(Constants.TraceLog)){//一些代码}response=tmpResponse;tmpResponse=null;}finally{if(tmpResponse!=null)tmpResponse.Dispose();}returnresponse;}为什么?请参阅链接文档中的示例。不,它是好吧...无论你把返回放在哪里,由using语句隐式生成的处理处理的finally块都会执行。你确定CA2000是myTracer而不是abc吗?我猜这个警告是因为MyResponse实现了IDisposable而你abcisnotdisposebeforereturn.(不管怎样,建议的override对warning没有影响。)warning很可能是关于MyResponse的,它是IDisposable的。为什么会warning呢?如果构造了一个MyResponse对象,但是稍微在代码之后该方法导致抛出异常,然后所有对该对象的引用都将丢失(我们只有一个,并且还没有设法返回它)。这意味着不能再对该对象调用Dispose,我们将依赖类Finalizer来清理所有资源。有关系吗?一般来说,只有在以下情况下才有意义:所以不,这不重要。如何处理?publicMyResponseMyMethod(stringarg){MyResponseabc=null;尝试{abc=newMyResponse();using(TracermyTracer=newTracer(Constants.TraceLog)){//一些代码返回abc;}}catch{if(abc!=null){abc.Dispose();}扔;这确保如果控制通过异常退出该方法,则abc为null或已被正确处理。更新事实证明,当使用这种处理时,从MyMethod中显式抛出的异常被重新抛出,并且第一个堆栈帧的行号被突变为指向抛出;陈述。实际上,这意味着如果您在MyResponse中有多个throw语句,并且它们使用相同的消息抛出相同类型的异常,那么当您捕获异常时,您将无法确定哪个throw是完全负责的。恕我直言,这是一个纯粹的学术问题,但我提到它是为了完整性。没关系。然而,与@Aliostad相反,我认为版本2,在using块之外的return是更好的风格。我的理由是:using块意味着“打开”和“关闭”事物。这是一个令人讨厌的交易。结束using块表示我们已经完成了我们的工作,可以安全地继续做其他事情,比如return。这个警告可能与“单一出口点”原则有关。在这里讨论:http://c2.com/cgi/wiki?SingleFunctionExitPoint以上是C#学习教程:从内部使用block返回,返回所有可以分享的内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。涉及侵权,请点击维权联系管理员删除。如需转载请注明出处:
