代码Anlysis规则CA2000 / CA2202 [英] Code Anlysis Rule CA2000 / CA2202

查看:256
本文介绍了代码Anlysis规则CA2000 / CA2202的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想确保我的编码遵循正确处置的对象,所以我执行这些规则的错误。但是我有这一段代码

I am trying to ensure my coding follows correct disposal of objects so I am enforcing these rules as errors. But I am having trouble with this section of code

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

class MyClass
{  
    public String ToXml()
    {
        var objSerializer = 
            new DataContractSerializer(GetType());
        var objStream = new MemoryStream();
        StreamReader objReader;

        String strResult;
        try
        {
            // Serialize the object
            objSerializer.WriteObject(objStream, this);

            // Move to start of stream to read out contents
            objStream.Seek(0, SeekOrigin.Begin);

            objReader = new StreamReader(objStream);

            try
            {
                // Read Contents into a string
                strResult = objReader.ReadToEnd();
            }
            finally
            {
                objReader.Dispose();
            }
        }
        finally
        {
            if (objStream != null)
            {
                // objStream.Dispose();
            }
        }

        return strResult;
    }
}

如果我注释掉 objStream .Dispose()我得到CA2000因为我不处置的对象,但如果我删除注释它,然后说,我处理了不止一次。

If I comment out objStream.Dispose() I get CA2000 as I am not disposing the object but if I remove the comment it then says I am disposing more than once.

还有什么是配置对象?还是我只是多个流打交道时,这样做不对?

What else is disposing the object? or am I just doing this wrong when dealing with multiple streams?

推荐答案

这情景一直烦我,现在好了。每隔几年我决定刷新的代码分析规则,自己运行的FxCop还是现在内置在Visual Studio代码分析。

This scenario has been annoying me as well now. Every couple of years I decide to refresh myself of the code analysis "rules" by running fxcop or the now built-in code analysis in Visual Studio.

我最初写这个码,以为我是做一个好公民的正常使用usings处置:

I originally wrote this code, thinking I was being a good citizen for properly using usings to dispose:

using (MemoryStream msDecrypt = new MemoryStream())
{
    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
    {
        csDecrypt.Write(eop.m_Ciphertext, 0, eop.m_Ciphertext.Length);
    }

    decrypted = msDecrypt.ToArray();
}

这在 CA2202代码结果块不处置的对象多次伟大对这条规则具有讽刺意味的是,它不是真正关心你的代码的问题,因为它更是保护你对别人的代码有问题。微软一直有文件,像样的数目有关如何Dispose模式(的 http://msdn.microsoft.com/en-us/library/b1yfkh5e(v = vs.110)的.aspx )应implmented。然而,看着这个代码分析规则( HTTP详情:// MSDN。 microsoft.com/en-us/library/ms182334.aspx )它

This block of code results in a CA2202 "Do not dispose objects multiple times" The great irony about this rule, is that it's not really about a problem with your code, as much as it is protecting you about a problem in others code. Microsoft has always had a decent amount of documentation about how the Dispose pattern (http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx) should be implmented. However, by looking at the details of this code analysis rule (http://msdn.microsoft.com/en-us/library/ms182334.aspx) it reveals the purpose of this rule

一个正确揭示这一规则的目的实现Dispose方法可以多次调用
未抛出异常。但是,这并不能完全保证,以
避免产生System.ObjectDisposedException你不应该调用
处置一次以上的上对象。

"A correctly implemented Dispose method can be called multiple times without throwing an exception. However, this is not guaranteed and to avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object."

在总之,这个规则是所有关于保护自己从没有遵守规则的人谁。

In short, this rule is all about protecting yourself from people who don't follow the rules.

当然,我修改了代码,如下所示:

Naturally I modified the code to look like this:

MemoryStream msDecrypt = new MemoryStream()    
//using (MemoryStream msDecrypt = new MemoryStream())
//{
    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
    {
        csDecrypt.Write(eop.m_Ciphertext, 0, eop.m_Ciphertext.Length);
    }

    decrypted = msDecrypt.ToArray();
//}

现在这个堆栈溢出后大家都痛苦地意识到新问题我们的朋友 CA2000处置损失范围之前对象 ...所以在这一点上,我只是面对伪称一分钟。做了一些谷歌搜索,发现这个职位。这时候,我恍然大悟,通过这两个CA的规则,你需要确保一切所有的代码分支处理一次且仅一次。于是我着手做这一点,一旦你意识到这是你需要做的是不是一个很难的问题。

Now everybody on this stack overflow post is painfully aware of the new problem, our friend CA2000 "Dispose objects before losing scope" ... so at this point I just face palmed for a minute. Did a few Google searches, and found this post. That's when it dawned on me, to pass for both CA rules, you need to ensure everything is disposed once and only once for all code branches. So I set out to do this, which isn't a hard problem once you realize this is what you need to do.

当然,代码进化到这一点:

Naturally, the code evolved to this:

MemoryStream msDecrypt = null;
CryptoStream csDecrypt = null;

try
{    
    msDecrypt = new MemoryStream();
    csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write);

    csDecrypt.Write(eop.m_Ciphertext, 0, eop.m_Ciphertext.Length);
    csDecrypt.FlushFinalBlock();
    decrypted = msDecrypt.ToArray();
}
finally
{
    if (csDecrypt != null)
    {
        csDecrypt.Dispose();
    }
    else if (msDecrypt != null)
    {
        msDecrypt.Dispose();
    }

}



最后,我有没码'T导致CA2000或CA2202。这个故事的寓意是,使用的语句,是少了很多有价值的比它在过去是,现在的代码分析规则以这种方式进化。

Finally, I had code that didn't result in a CA2000 or CA2202. The moral of the story is that the USING statement, is a lot less valuable than it was in the past now that code analysis rules have evolved in this way.

有几个不同的方法,你可以编写代码,使这项工作,我只是选择了一个不明确的混合呼叫使用语句处置的方式,因为我相信这是更简单的结构化的方式,将向以及阅读防止某些人只是去和包装另外用它周围,导致原来不知不觉的问题。

There are a few different ways you can write the code to make this work, I just chose a way that doesn't mix explicit calls to dispose with using statements, because I believe this to be simpler to read as well as structured in a way that would prevent someone from just going and wrapping another using around it, resulting in the originally issue unknowingly.

这篇关于代码Anlysis规则CA2000 / CA2202的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆