代码分析-不要多次处置对象

发布于 2025-01-01 11:20:12 字数 1091 浏览 2 评论 0原文

我尝试遵循此方法的代码分析规则:

public static string Encrypt(string password)
{
    string myPassword = string.Empty;
    if (!string.IsNullOrEmpty(password))
    {
        myPassword = password;
        byte[] Value = System.Text.Encoding.UTF8.GetBytes(myPassword);
        SymmetricAlgorithm mCSP = new RijndaelManaged();
        mCSP.Key = _key;
        mCSP.IV = _initVector;
        using (ICryptoTransform ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV))
        {
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write))
                {
                    cs.Write(Value, 0, Value.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                    myPassword = Convert.ToBase64String(ms.ToArray());
                }
            }
        }
    }
    return myPassword;
}

添加了所有 Try {} Finaly{} 块,但它仍然对我大喊大叫,说我不遵守规则 2202。 任何人都可以帮我解决这个问题吗?

是的,我读过有关此主题的其他帖子并尝试应用它, 但最后我仍然收到同样的信息。

i have tried following the rules of code analysis on this method:

public static string Encrypt(string password)
{
    string myPassword = string.Empty;
    if (!string.IsNullOrEmpty(password))
    {
        myPassword = password;
        byte[] Value = System.Text.Encoding.UTF8.GetBytes(myPassword);
        SymmetricAlgorithm mCSP = new RijndaelManaged();
        mCSP.Key = _key;
        mCSP.IV = _initVector;
        using (ICryptoTransform ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV))
        {
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write))
                {
                    cs.Write(Value, 0, Value.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                    myPassword = Convert.ToBase64String(ms.ToArray());
                }
            }
        }
    }
    return myPassword;
}

added all the Try {} Finaly{} blocks, but it was still yelling at me that i dont respect rule 2202.
anyone can give me a hand with this?

yes, i have read other posts about this subject and tried applying it,
but at the end i still get the same message.

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

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

发布评论

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

评论(4

も让我眼熟你 2025-01-08 11:20:12

要消除 cs 的 CA2202 警告,只需删除对其 Close 方法的调用即可。

ms 的 CA2202 问题稍微复杂一些。出现此警告是因为 CryptoStream 厚颜无耻地处置通过构造函数接收到的流,这意味着对 ms.Close() 进行了一次不适当的调用,您可以不要回避。好消息是,这种不合时宜的处置对您的情况没有副作用,双重处置也是如此,因此您可以安全地使用 SuppressMessageAttribute 并忽略该问题。 (对于您实际上需要传递流以通过诸如 CryptoStream 之类的东西来避免其不可阻止的处置的情况,通常的技术是使用流子类,其处置可以通过其实例化代码来阻止。)

To get rid of the CA2202 warning for cs, simply remove the call to its Close method.

The CA2202 problem for ms is a wee bit more complex. The warning is cropping up because CryptoStream has the effrontery to dispose the stream it received via is constructor, which means that there's one inappropriate call to ms.Close() that you can't avoid. The good news is that this untimely disposition has no side-effects in your case, and the same goes for the double disposition, so you can safely slap on a SuppressMessageAttribute and ignore the problem. (For cases where you actually need to passed stream to survive its unpreventable disposition by something like CryptoStream, the usual technique is to use a stream subclass whose disposition can be prevented by its instantiating code.)

再见回来 2025-01-08 11:20:12

去掉这两行,它们是不需要的:

cs.FlushFinalBlock();
cs.Close();

Get rid of these two lines, they aren't needed:

cs.FlushFinalBlock();
cs.Close();
权谋诡计 2025-01-08 11:20:12

按照有关此主题的文档应该会生成以下代码:

public static string Encrypt(string password)
{
    string myPassword = string.Empty;
    if (!string.IsNullOrEmpty(password))
    {
        myPassword = password;
        byte[] Value = System.Text.Encoding.UTF8.GetBytes(myPassword);
        SymmetricAlgorithm mCSP = new RijndaelManaged();
        mCSP.Key = _key;
        mCSP.IV = _initVector;
        using (ICryptoTransform ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV))
        {
            System.IO.MemoryStream ms = null;
            try
            {
                ms = new System.IO.MemoryStream()
                var tmp = ms;
                using (CryptoStream cs = new CryptoStream(ms, ct, 
                                                       CryptoStreamMode.Write))
                {
                    ms = null;

                    cs.Write(Value, 0, Value.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                    myPassword = Convert.ToBase64String(tmp.ToArray());
                }
            }
            finally
            {
                if(ms != null)
                    ms.Dispose();
            }
        }
    }
    return myPassword;
}

Following the documentation on this topic should lead to this code:

public static string Encrypt(string password)
{
    string myPassword = string.Empty;
    if (!string.IsNullOrEmpty(password))
    {
        myPassword = password;
        byte[] Value = System.Text.Encoding.UTF8.GetBytes(myPassword);
        SymmetricAlgorithm mCSP = new RijndaelManaged();
        mCSP.Key = _key;
        mCSP.IV = _initVector;
        using (ICryptoTransform ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV))
        {
            System.IO.MemoryStream ms = null;
            try
            {
                ms = new System.IO.MemoryStream()
                var tmp = ms;
                using (CryptoStream cs = new CryptoStream(ms, ct, 
                                                       CryptoStreamMode.Write))
                {
                    ms = null;

                    cs.Write(Value, 0, Value.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                    myPassword = Convert.ToBase64String(tmp.ToArray());
                }
            }
            finally
            {
                if(ms != null)
                    ms.Dispose();
            }
        }
    }
    return myPassword;
}
黑色毁心梦 2025-01-08 11:20:12

有关此分析警告的文档 (http://msdn.microsoft.com/en- us/library/ms182334.aspx) 给出了这个示例,与您的示例类似,因为它正在操作流:

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}

但这仍然给出错误。下面将解决该错误:

Stream stream = null;
StreamWriter writer = null;
try
{
   stream = new FileStream("file.txt", FileMode.OpenOrCreate);
   writer = new StreamWriter(stream))

   // Do some stuff on the stream writer..
}
finally
{
   if(writer != null)
       writer.Dispose();
   else if(stream != null)
       stream.Dispose();
}

原因很简单;如果作者总是为您处理流。只有在 writer 未成功创建的情况下,您才应该自行处理流。但我必须承认我更喜欢下面的语法,如果您创建 MemoryStream 而不是 FileStream,发生异常的机会很小,我更喜欢抑制 CA。请注意,您可以堆叠 using 语句,因此通常不需要额外的“嵌套级别”。

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
using (StreamWriter writer = new StreamWriter(stream))
{
    // Use the writer object...
}

The documentation on this analysis warning (http://msdn.microsoft.com/en-us/library/ms182334.aspx) gives this example, similar to yours in that it's manipulating streams:

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}

but this still gives the error. The following will solve the error:

Stream stream = null;
StreamWriter writer = null;
try
{
   stream = new FileStream("file.txt", FileMode.OpenOrCreate);
   writer = new StreamWriter(stream))

   // Do some stuff on the stream writer..
}
finally
{
   if(writer != null)
       writer.Dispose();
   else if(stream != null)
       stream.Dispose();
}

The reason is simple; if the writer will always dispose the stream for you. Only in the scenario the writer is not successfully created should you dispose the stream yourself. But I must admit I like the following syntax a lot more, and if you create a MemoryStream instead of a FileStream the chance of an exception occurring is small and I would prefer suppressing the CA. Please notice that you can stack using statements, so a extra 'nesting level' is often not required.

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
using (StreamWriter writer = new StreamWriter(stream))
{
    // Use the writer object...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文