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