你如何“正确”地做到这一点?当您的实现是空方法时实施 Dispose() (根据 FxCop)? (CA1063)

发布于 2024-12-28 15:01:40 字数 1994 浏览 2 评论 0原文

我有一个接口的实现,并且该接口扩展了 IDisposable。在我的接口的特定实现中,我不需要释放任何东西,所以我只有一个空的 Dispose() 方法。

public interface IMyStuff : IDisposable
{
}

public MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
    }
}

现在在 FxCop 中,这会导致 CA1063:

Error, Certainty 95, for ImplementIDisposableCorrectly
{
    Resolution   : "Provide an overridable implementation of Dispose(
                   bool) on 'MyStuffImpl' or mark the type as sealed. 
                   A call to Dispose(false) should only clean up native 
                   resources. A call to Dispose(true) should clean up 
                   both managed and native resources."
}
CriticalWarning, Certainty 75, for CallGCSuppressFinalizeCorrectly
{
    Resolution   : "Change 'MyStuffImpl.Dispose()' to call 'GC.SuppressFinalize(
                   object)'. This will prevent derived types that introduce 
                   a finalizer from needing to re-implement 'IDisposable' 
                   to call it."
}
Error, Certainty 95, for ImplementIDisposableCorrectly
{
    Resolution   : "Modify 'MyStuffImpl.Dispose()' so that it 
                   calls Dispose(true), then calls GC.SuppressFinalize 
                   on the current object instance ('this' or 'Me' in Visual 
                   Basic), and then returns."
}

因此,看起来我可以通过以下两种方式之一解决此问题:


使类密封

public sealed MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
    }
}

实现典型模式的一部分:

public MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
    }
}

就我而言,我不这样做我不打算扩展这个实现,所以我可能会通过将其密封来解决它,但我承认我并不真正理解为什么密封与否很重要。

另外,仅仅因为我的类是密封的,FxCop 不再告诉我 Dispose() 应该调用 GC.SupressFinalize(this); 但这真的是这样吗?在 .NET 中,总是在 Dispose 中调用 SupressFinalize 是否“更好”?

I have an implementation of an interface, and that interface extends IDisposable. In my particular implementation of the interface, I don't need to dispose anything, so I just have an empty Dispose() method.

public interface IMyStuff : IDisposable
{
}

public MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
    }
}

Now in FxCop, this results in a CA1063:

Error, Certainty 95, for ImplementIDisposableCorrectly
{
    Resolution   : "Provide an overridable implementation of Dispose(
                   bool) on 'MyStuffImpl' or mark the type as sealed. 
                   A call to Dispose(false) should only clean up native 
                   resources. A call to Dispose(true) should clean up 
                   both managed and native resources."
}
CriticalWarning, Certainty 75, for CallGCSuppressFinalizeCorrectly
{
    Resolution   : "Change 'MyStuffImpl.Dispose()' to call 'GC.SuppressFinalize(
                   object)'. This will prevent derived types that introduce 
                   a finalizer from needing to re-implement 'IDisposable' 
                   to call it."
}
Error, Certainty 95, for ImplementIDisposableCorrectly
{
    Resolution   : "Modify 'MyStuffImpl.Dispose()' so that it 
                   calls Dispose(true), then calls GC.SuppressFinalize 
                   on the current object instance ('this' or 'Me' in Visual 
                   Basic), and then returns."
}

So, it looks like I can resolve this in one of 2 ways:


Make the class sealed:

public sealed MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
    }
}

Implement part of the typical pattern:

public MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
    }
}

In my case, I don't plan on this implementation ever being extended, so I will probably resolve it by making it sealed, but I admit I don't really understand why it matters if it is sealed or not.

Also, just because my class is sealed, FxCop no longer tells me that Dispose() should call GC.SupressFinalize(this); but is that really true? Is it "better" in .NET to just always call SupressFinalize in Dispose regardless?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温柔少女心 2025-01-04 15:01:40

除非您的实例具有终结器,否则 SuppressFinalize() 毫无意义。
如果您的类没有终结器,但未sealed,您仍应SuppressFinalize,以防继承类添加终结器。

您的两个选项都是正确的,除了 Dispose(bool) 需要protected virtual

SuppressFinalize() is meaningless unless your instance has a finalizer.
If your class doesn't have a finalizer, but is not sealed, you should still SuppressFinalize, in case an inherited class adds a finalizer.

Both of your options are correct, except that Dispose(bool) needs to be protected virtual.

静若繁花 2025-01-04 15:01:40

在“实现典型模式的一部分”选项中,您应该使您的 Dispose(bool) 方法 protected virtual

protected virtual void Dispose(bool disposing) 
{ 
} 

这将为子类提供处理任何资源的机会他们管理。这就是“提供 Dispose(bool) 的可重写实现”中“可重写”的含义。

当然,public virtual 也能满足 FxCop。

In your "implement part of the typical pattern" option, you should make your Dispose(bool) method protected virtual:

protected virtual void Dispose(bool disposing) 
{ 
} 

That will provide subclasses an opportunity to handle disposal of any resources they manage. That's the meaning of "overridable" in "Provide an overridable implementation of Dispose(bool)"

Of course, public virtual would also satisfy FxCop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文