今天早些时候,当我对某些代码进行代码分析时,我遇到了CA1063。
我有两个问题:
为什么以下代码不会导致CA1063,即使它明显违反了某些要求(例如Dispose被覆盖)
代码的实际问题是什么导致复杂的方案有一个由密封的Dispose()和Finalizer等调用的虚拟Dispose(bool)....
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Foobar : IDisposable { public Foobar() { Console.Out.WriteLine("Constructor of Foobar"); } public virtual void Dispose() { Console.Out.WriteLine("Dispose of Foobar"); GC.SuppressFinalize(this); } ~Foobar() { Console.Out.WriteLine("Finalizer of Foobar"); } } class Derived : Foobar { public Derived() { Console.Out.WriteLine("Constructor of Derived"); } public override void Dispose() { Console.Out.WriteLine("Dispose of Derived"); GC.SuppressFinalize(this); base.Dispose(); } ~Derived() { Console.Out.WriteLine("Finalizer of Derived"); } } class Program { static void Main() { Console.Out.WriteLine("Start"); using (var foo = new Derived()) { Console.Out.WriteLine("..."); } Console.Out.WriteLine("End"); } } }
答案 0 :(得分:3)
最初,Microsoft期望许多类型的对象将封装托管和非托管资源,即使特定的可继承类没有封装任何非托管资源,从它派生的类也可能这样做。即使这种想法在很大程度上是错误的(将非托管资源分离到他们自己的对象中通常要好得多,然后可以将其用作托管资源),旨在处理任意混合的托管和非托管资源的模式成为一个既定的先例
尽管完整的Dispose模式的部分是愚蠢的,但正确的简化不会遗漏很多。清理代码应该在受保护的虚方法中,以便允许派生类添加自己的逻辑但仍链接到父类方法;如果该方法的名称为Dispose
,则它必须具有与无参数Dispose
方法不同的签名[尽管我自己的偏好是具有不同名称的无参数方法]。我对微软模式的最大抱怨是,它要求每个派生类都有自己的逻辑来防止重复处理;让基类在非虚拟Dispose
实现中处理它会更加清晰。