vs2010 中的 fxcop CA2213 错误

发布于 2024-09-26 18:52:27 字数 1768 浏览 1 评论 0原文

我有以下代码: 包含两个一次性成员的一次性类。 其中之一是使用 new() 方法进行初始化,另一个是使用静态工厂方法进行初始化。 我还有静态代码分析规则,其中 CA2213 为错误。

    public class DisposableClass : IDisposable
{
    private WebClient m_DisposableMember1;

    public WebClient DisposableMember1
    {
        get
        {
            if (m_DisposableMember1 == null)
            {
                m_DisposableMember1 = new WebClient();
            }
            return m_DisposableMember1;
        }
    }

    private WebClient m_DisposableMember2;

    public WebClient DisposableMember2
    {
        get
        {
            if (m_DisposableMember2 == null)
            {
                m_DisposableMember2 = Factory.Create();
            }
            return m_DisposableMember2;
        }
    }


    #region Finalize/Dispose Pattern
    private bool m_IsDisposed = false;

    //Implement IDisposable.
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~DisposableClass()
    {
        Dispose(false);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!m_IsDisposed)
        {
            if (disposing)
            {
                DisposableMember1.Dispose();
                // DisposableMember2 in not disposed and not notified by fxCop
            }

            m_IsDisposed = true;
        }
    }
    #endregion Finalize/Dispose Pattern

}

这是简单工厂类:

    public static class Factory
{
    public static WebClient Create()
    {
        return new WebClient();
    }
}

当我调用 DisposableMember1 属性的 Dispose() 方法时,我得到 CA2213。 当我调用 m_DisposableMember1 成员的 Dispose() 方法时,我没有收到此错误。

更重要的是,我没有收到 m_DisposableMember2 的此错误(它是使用静态工厂初始化的),并且它没有被处置。

有人熟悉这个问题吗?什么会导致这种行为?

I have the following code:
A disposable class that contains two disposable members.
One of them is being initialized using new() method, and the other using static factory method.
I Also have static code analisys rules, with CA2213 as error.

    public class DisposableClass : IDisposable
{
    private WebClient m_DisposableMember1;

    public WebClient DisposableMember1
    {
        get
        {
            if (m_DisposableMember1 == null)
            {
                m_DisposableMember1 = new WebClient();
            }
            return m_DisposableMember1;
        }
    }

    private WebClient m_DisposableMember2;

    public WebClient DisposableMember2
    {
        get
        {
            if (m_DisposableMember2 == null)
            {
                m_DisposableMember2 = Factory.Create();
            }
            return m_DisposableMember2;
        }
    }


    #region Finalize/Dispose Pattern
    private bool m_IsDisposed = false;

    //Implement IDisposable.
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    ~DisposableClass()
    {
        Dispose(false);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!m_IsDisposed)
        {
            if (disposing)
            {
                DisposableMember1.Dispose();
                // DisposableMember2 in not disposed and not notified by fxCop
            }

            m_IsDisposed = true;
        }
    }
    #endregion Finalize/Dispose Pattern

}

This is the simple factory class:

    public static class Factory
{
    public static WebClient Create()
    {
        return new WebClient();
    }
}

When I call the Dispose() method of the DisposableMember1 property, I get CA2213.
When I call the Dispose() method of the m_DisposableMember1 member, I don't get this error.

More over, I don't get this error for m_DisposableMember2 (Wich was initialized using the static factory), and it is not being disposed.

Does anybody familiar with this issue? What can cause this behavior?

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

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

发布评论

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

评论(2

旧瑾黎汐 2024-10-03 18:52:27

CA2213 在识别应该处理的字段方面并不是特别积极。在其他潜在问题中,它仅考虑从构造函数调用直接分配的字段。通过属性或从构造函数调用以外的源分配字段值不会导致目标字段被规则包含在“应处置”字段池中。

CA2213 is not particularly aggressive about identifying fields that ought to be disposed. Amongst other potential problems, it only considers fields that are directly assigned from a constructor invocation. Assignment of a field value via a property or from a source other than a constructor invocation do not result in the target field being included in the pool of "should be disposed" fields by the rule.

戏舞 2024-10-03 18:52:27

您对这个工具的智能期望有点太高了。该属性是该字段的别名,这对于人眼来说是显而易见的。它需要相当复杂的分析才能让工具看到这一点。 FxCop 就是没有那种马力。您的代码实际上是有问题的。如果客户端代码从未使用过该属性,那么您将创建 WebClient 对象并立即处置它。请改用该字段,测试 null 和 Dispose()。

第二个字段的问题可能是由于需要该工具来避免不必要的警告而引起的。只有当它能够绝对确定该字段是否已初始化时,它才会抱怨。这里同样缺乏智慧,它无法判断工厂总是返回一个非空引用。只有当它看到类本身使用了构造函数时,才能确定需要释放该字段。

这是一个很好的工具,但并不完美。

You are expecting a bit too much out of the smarts of this tool. That the property is an alias for the field is only obvious to human eyes. It requires pretty sophisticated analysis to let a tool see that. FxCop just doesn't have that kind of horse power. Your code is in fact questionable. If the property was never used by the client code then you'll create the WebClient object and immediately dispose it. Use the field instead, test for null and Dispose().

The problem with the second field is probably induced by the need for the tool to avoid unnecessary warnings. It will only complain if it can determine with absolute certainty that the field is ever initialized. Same kind of lack of smarts here, it can't tell that the factory always returns a non-null reference. Only when it sees the constructor being used in the class itself can it be sure that the field needs to be disposed.

It's a good tool, not perfect.

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