【发布时间】:2015-08-26 23:44:51
【问题描述】:
在几个地方,人们建议使用private void Dispose(bool) 来表示IDisposable 模式。不过,这似乎已经过时了(至少对于未密封的类而言),因为新建议的模式(根据 Microsoft)是 protected virtual void Dispose(bool)。
问题是,代码分析不会报告 private void Dispose(bool) 违反 CA1063,即使它似乎直接违反了模式。
这是怎么回事? private void Dispose(bool) 是否以某种方式被调用(或编译为类似于 protected virtual Dispose(bool) 的东西?
如果这是代码分析的一些问题并且是不正确的模式,有没有办法检测到这一点?可能与 StyleCop 一起使用?
编辑:经过考虑,基类是否可以调用base.Dispose(),而private void Dispose(bool)?即使它不能传入参数?
编辑:示例
public class A : IDisposable
{
~A()
{
this.Dispose(false);
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing) // Should be protected virtual void Dispose(bool)
{
Console.WriteLine("A");
}
}
public class B : A
{
protected virtual void Dispose(bool disposing) // Proper pattern.
{
Console.WriteLine("B");
}
}
public static class Program
{
static void Main(string[] args)
{
A a = new A();
a.Dispose(); // Prints "A"
B b = new B();
b.Dispose(); // Prints "A"!
}
}
从这里可以看出,它使得使用 dispose 模式变得非常笨拙。
您可以通过隐藏public void Dispose(void) 然后在某处调用base.Dispose() 来解决这个问题。然后在调用A b = new B(); b.Dispose(); 时调用B b = new B(); b.dispose(); except 时,这与正确的处理模式“相似”,它只调用A 的Dispose 方法。
public class B : A
{
public void Dispose() // Causes CA error with or without "new".
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) // Proper pattern.
{
base.Dispose(); // Writes "A" (without quotes).
Console.WriteLine("B");
}
}
基本上,这整件事看起来很糟糕。我们是否知道 CA 接受 private void Dispose(bool) 是否是一个错误,是否有办法至少向 StyleCop 发出警告?
编辑:我认为我不应该接受 Alexandre 的回答,因为相对于我的问题,它基本上可以归结为“可能是一个错误”,以及一些应该作为评论的内容。如果其他人有更确凿的结论,我认为这将是一个更合适的答案。
【问题讨论】:
-
密封类呢? protected 应该用于公开类,private 用于密封。
-
它适用于任何一个问题。我们发现了几个未密封类没有引发问题的地方。不过,这是有道理的,密封类需要私有。尽管如此,如果类未密封(它也应该知道这一点),那么 CA 抛出它会很好。我认为我的编辑说明了为什么它可能不会完全摆脱困境,但它仍然有点烦人。
-
调用
base.Dispose()显然违反了这种模式,所以我认为它不能解释它。我同意您最初的想法,即代码分析应该报告您提出的案例。 -
我会完全使用another pattern。
-
这篇文章有很多问题。哪个是基本问题:为什么推荐模式发生了变化,或者为什么代码分析没有抱怨?
标签: c# code-analysis idisposable fxcop