从内部使用块返回是否可以

Shi*_*iji 27 c# return

我正在进行代码审查,并找到了许多具有以下格式的代码:

public MyResponse MyMethod(string arg)
{
    using (Tracer myTracer = new Tracer(Constants.TraceLog))
    {
        MyResponse abc = new MyResponse();

        // Some code

        return abc;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行代码分析时,我得到一个CA2000警告Microsoft.Reliability

应该将代码重写为:

public MyResponse MyMethod(string arg)
{
   MyResponse abc = new MyResponse();

   using (Tracer myTracer = new Tracer(Constants.TraceLog))
   {
       // Some code
   }
   return abc;
}
Run Code Online (Sandbox Code Playgroud)

或者没关系?

编辑

报告警告的行是:

MyResponse abc = new MyResponse();
Run Code Online (Sandbox Code Playgroud)

MyResponse是标准的数据集.

完整的错误消息是:

警告150 CA2000:Microsoft.Reliability:在方法'xxxxx(Guid,Guid)'中,对象'MyResponse'未沿所有异常路径放置.在对所有引用超出范围之前,在对象'MyResponse'上调用System.IDisposable.Dispose.

Luk*_*keH 15

不,没关系.

无论你把它放在哪里,finallyusing句柄处理处理隐式生成的块都将执行return.

你确定了CA2000涉及到myTracerabc?我猜这个警告正在发生,因为MyResponse工具IDisposable和你abc在返回之前没有处理.(无论哪种方式,建议的重写都不会对警告产生任何影响.)

  • @Daniel:OP问"可以从使用块内部返回"和"应该重写代码以将返回移到使用块之外".我正在回答这些问题,然后*推测*问题的真正根本原因(推测因为OP没有提供足够的具体细节).你自己的答案提供了(推定的)真实问题的解决方案,如果你觉得它值得,我很乐意在这里重现类似的东西. (3认同)

Dan*_*rth 11

您的重写不会修复CA2000警告,因为问题不是Tracer对象,而是MyResponse对象.
文件说明:

以下是使用语句不足以保护IDisposable对象并可能导致CA2000发生的一些情况.
返回一次性对象需要在使用块之外的try/finally块中构造对象.

要修复警告而不弄乱异常的堆栈跟踪(< - 单击,这是一个链接),请使用以下代码:

public MyResponse MyMethod(string arg)
{
   MyResponse tmpResponse = null;
   MyResponse response = null;
   try
   {
       tmpResponse = new MyResponse();

       using (Tracer myTracer = new Tracer(Constants.TraceLog))
       {
           // Some code
       }

       response = tmpResponse;
       tmpResponse = null;
    }
    finally
    {
        if(tmpResponse != null)
            tmpResponse .Dispose();
    }
    return response;
}
Run Code Online (Sandbox Code Playgroud)

为什么?请参阅链接文档中的示例.