CA2000的级别变量和方法之间的区别警告

问题描述:

我正在使用.net在SPA应用程序的Web Api上工作。当我在方法中使用实例化对象时,我得到CA2000警告。但是当我在课堂上宣布同一个对象时,CA2000警告消失。从下面,示例1给出CA2000警告,而示例2没有。为什么?CA2000的级别变量和方法之间的区别警告

实施例1-

public class CodeGenAPIController : ApiResponseController 
{ 
    NextGenCodeGen.CodeGenerator getEndPoint(TokenManager.TokenData tokenData, int BranchId) 
    { 
     NextGenCodeGen.CodeGenerator ret = null; 
     lock (branchGenLock) 
     { 
      if (branchGenerators.ContainsKey(BranchId)) 
       ret = branchGenerators[BranchId]; 
     } 
     if (ret == null) 
     { 
      string services = ConfigurationValuesAPIController.GetBranchProperties(tokenData.DatabaseIdentifier, BranchId).FirstOrDefault(x => x.Key == "AvailableCodeGenServices").Value; 

      string[] endpoints = services.Split(new char[] { ' ', '.' }, StringSplitOptions.RemoveEmptyEntries); 
      if (endpoints.Length == 0) 
       throw new ArgumentOutOfRangeException("AvailableCodeGenServices", 
        string.Format("There appear to be no Code Generation Services configured for branch {0}", BranchId)); 

      string endpoint = endpoints[0]; 
      if (!endpoint.ToLower().EndsWith(".asmx")) 
       endpoint = endpoint + ".asmx"; 

      //OBJECT INSTANTIATION INSIDE THE METHOD 
      ret = new My_API.NextGenCodeGen.CodeGenerator() { Url = endpoint, UseDefaultCredentials = true};** 
      lock(branchGenLock) 
      { 
       branchGenerators[BranchId] = ret; 
      } 
     } 
     return ret;   
    } 
} 

实施例2-

public class CodeGenAPIController : ApiResponseController 
{ 
    //OBJECT INSTANTIATION OUTSIDE THE METHOD AT THE CLASS LEVEL 
    NextGenCodeGen.ARGenTCodeGenerator retVal = new My_API.NextGenCodeGen.ARGenTCodeGenerator(); 

    NextGenCodeGen.CodeGenerator getEndPoint(TokenManager.TokenData tokenData, int BranchId) 
    { 
     retVal = null; 
     lock (branchGenLock) 
     { 
      if (branchGenerators.ContainsKey(BranchId)) 
       retVal = branchGenerators[BranchId]; 
     } 
     if (retVal == null) 
     { 
      string services = ConfigurationValuesAPIController.GetBranchProperties(tokenData.DatabaseIdentifier, BranchId).FirstOrDefault(x => x.Key == "AvailableCodeGenServices").Value; 

      string[] endpoints = services.Split(new char[] { ' ', '.' }, StringSplitOptions.RemoveEmptyEntries); 
      if (endpoints.Length == 0) 
       throw new ArgumentOutOfRangeException("AvailableCodeGenServices", 
        string.Format("There appear to be no Code Generation Services configured for branch {0}", BranchId)); 

      string endpoint = endpoints[0]; 
      if (!endpoint.ToLower().EndsWith(".asmx")) 
       endpoint = endpoint + ".asmx"; 
      retVal = new My_API.NextGenCodeGen.CodeGenerator(); 
      retVal.Url = endpoint; 
      retVal.UseDefaultCredentials = true; 

      lock (branchGenLock) 
      { 
       branchGenerators[BranchId] = retVal; 
      } 
     } 
     return retVal; 
    } 
} 

在类的情况下,它应该行程和CA2213 CA2000没有。 https://msdn.microsoft.com/en-us/library/ms182328.aspx

看起来像CA2213的限制,它无法弄清楚如何处理实现IDisposable的基类。在下面的例子中,FileIo继承自IoBase并且不会引发警告。 FileIo2只实现IDisposable和确实提出警告。

public class IoBase : IDisposable 
{ 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
    protected virtual void Dispose(bool disposing) 
    { 
    } 
} 
public class FileIo: IoBase 
{ 
    private Stream io = new FileStream("c:\tmp\tmp.txt", FileMode.OpenOrCreate); 
} 

public class FileIo2 : IDisposable 
{ 
    private Stream io = new FileStream("c:\tmp\tmp.txt", FileMode.OpenOrCreate); 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 
    protected virtual void Dispose(bool disposing) 
    { 
    } 
} 

通过在类级声明变量,你是它确定范围的类的实例。即使你在函数中重新初始化它,它的作用域仍然是函数的外部。根据CA2000文档,这不会触发警告,因为“所有对它的引用都超出了范围”是不正确的。

官方文档:https://msdn.microsoft.com/en-us/library/ms182289.aspx

由于该警告是在第一个例子中发行,这应该表明My_API.NextGenCodeGen.CodeGenerator实现IDisposable。如果属实,那么考虑在该类中添加一个Dispose处理函数,并在那里执行任何类拥有的IDisposable变量清理。垃圾收集将处理其余部分。

如果您ApiResponseController继承ApiController,那么你已经得到了车辆,你只是爱硬盘呢:

public abstract class ApiController : IHttpController, IDisposable