我正在使用.net为一个SPA应用程序开发Web Api。当我使用实例化方法中的对象时,我收到CA2000警告。但是当我在类级别声明相同的对象时,CA2000警告就会消失。从下面,示例1给出了CA2000警告,而示例2没有。为什么?
示例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;
}
}
答案 0 :(得分:0)
通过在类级别声明变量,您可以将其作用于类实例。即使您在函数中重新初始化它,它的范围仍然是函数的外部。根据CA2000文档,这不会触发警告,因为"所有对它的引用超出范围"不是真的。
官方文件:https://msdn.microsoft.com/en-us/library/ms182289.aspx
由于在第一个示例中发出了警告,这应该表明My_API.NextGenCodeGen.CodeGenerator
实现了IDisposable
。如果为true,则考虑在此类中添加Dispose
处理程序,并在那里执行任何类拥有的IDisposable
变量清理。垃圾收集将处理其余的事情。
如果您的ApiResponseController
继承ApiController
,那么您已经拥有了这辆车,那么您只需驾驶它:
public abstract class ApiController : IHttpController, IDisposable
答案 1 :(得分:0)
在课堂案例中,应该行程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)
{
}
}