Bee*_*006 5 c# code-analysis fxcop
以下代码为Main的第一行生成CA2000(" 丢失范围之前的Dispose对象 ")违规,但不生成第二行.我真的很喜欢第二行的CA2000违规,因为这是我工作的大型代码库中常见的(显然简化的)模式.
有谁知道为什么第二行没有产生违规?
public static void Main()
{
new Disposable();
MakeDisposable();
}
private static Disposable MakeDisposable() { return new Disposable(); }
private sealed class Disposable : IDisposable
{
public void Dispose()
{
}
}
Run Code Online (Sandbox Code Playgroud)
简短的回答是,CA2000已经破裂,不太可能很快得到修复.请参阅此错误报告,这几乎是您的问题:
特别是警告CA2000是一个已知问题的规则,我们将无法以当前形式修复它.
更长的答案是让CA2000正确是很难的.在过去的Visual Studio版本中,特别是2010年,在整个地方都发出了错误的CA2000警告,并且没有任何办法可以让它们消失.搜索Stack Overflow以查找有关它的任何问题.
即使在您可以消除警告的情况下,解决方法也几乎比将其留在原地更糟糕.问题是,在您遇到的情况下,您不希望在它离开工厂方法范围之前处置对象.除此之外,你会这样做 - 如果它抛出异常.在这种情况下,方法的返回值将丢失,并且调用者无法为自己处置该对象.
不幸的是,试图弄清楚这意味着对编译的IL进行程序流分析,以确定是否有任何代码路径(包括特殊路径)允许对象泄漏.最终的结果是,几乎任何你尝试IDisposable从方法返回的情况都会产生错误.
微软通过做两件事做出了回应:
与Roslyn编译器重写相比,FxCop等工具可以进行一些源级分析,在这种情况下可能更容易正确.同时,普遍的共识是,关闭CA2000.
如果您感到好奇,一些测试似乎确认当前(2013)CA规则仅在本地包含的本地构造的实例IDisposable超出范围时触发.IOW,对象不能离开你的方法new,或者CA忽略它.这让我相信CA根本就没有深入研究它的分析方法调用.除了试图消除误报之外,它还可能是通过削减一些昂贵的支票来加速CA流程的整体尝试的一部分,我相信这些支票发生在2010年和2012年之间?
如果我在你的例子中添加一点,你可以看到哪些明显的模式会得到警告:
class Program
{
public static void Main()
{
new Disposable(); // CA2000
IDisposable x;
MakeDisposable(out x);
Test();
}
public static Disposable Test()
{
IDisposable z;
var x = MakeDisposable(out z);
var y = new Disposable(); // CA2000
return x;
}
private static Disposable MakeDisposable(out IDisposable result)
{
result = new Disposable();
new Disposable(); // CA2000
return new Disposable();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
287 次 |
| 最近记录: |