如何满足CA2202(不要多次处理对象)

How to satisfy CA2202 (Do not dispose objects multiple times)

This question may seem to you duplicate of CA2202, how to solve this case which has an accepted answer. But you may realize that accepted answer has 5 down votes based on poor quality. Also any other up voted answers are not actually solves the issue. Most of them explains how to suppress the rule or debates about how wrong this rule is and why we should ignore it. Since that rule is there, there should be a way to satisfy it and I'm looking for community support to solve that issue.

我正在想办法满足CA2202 in the following code. I understand that the issue here is, using statement also disposes the encryptedStream object. But if I remove the finally part, it starts to throw CA2000

那么,符合CA2202和CA2000的正确写法是什么

byte[] result;

MemoryStream encryptedStream = null;
try
{
    encryptedStream = new MemoryStream();
    using (var cryptStream = new CryptoStream(encryptedStream, cryptoTransform, CryptoStreamMode.Write))
    {
        cryptStream.Write(inputInBytes, 0, inputInBytes.Length);
        cryptStream.FlushFinalBlock();
        result = encryptedStream.ToArray();
    }
}
finally
{
    encryptedStream?.Dispose();
}
string output = Convert.ToBase64String(result);

真的,真的,抑制警告。警告是错误的。没关系做。 :-)

Google 搜索 "CA2202 nested using",您会发现许多关于此问题的 Whosebug 和 MSDN 论坛帖子。 https://www.google.com/search?q=ca2202+nested+using

最终,CA2202 和 CA2000 受到限制,因为它们无法理解嵌套 IDisposable 对象的行为。一些流可以配置为让底层流保持打开状态,但通常它们不会。打压果然是正解。问题是你在努力成为一个好公民,所以你在努力遵守给你的警告。但是静态分析还不够聪明,无法处理这个问题。

这是对您问题的字面回答,因为它不会在不抑制它们的情况下发出 CA 警告,并且只会调用每个 Dispose 一次:

MemoryStream encryptedStream = null;
CryptoStream cryptStream = null;
try {
    encryptedStream = new MemoryStream();
    cryptStream = new CryptoStream(encryptedStream, cryptoTransform, CryptoStreamMode.Write);
    cryptStream.Write(inputInBytes, 0, inputInBytes.Length);
    cryptStream.FlushFinalBlock();
    result = encryptedStream.ToArray();
} finally {
    if (cryptStream != null) {
        cryptStream.Dispose();
   } else {
        if (encryptedStream != null) encryptedStream.Dispose();
   }
}
string output = Convert.ToBase64String(result);

但是任何称职的开发人员都应该看看这个然后去 "hmm, it's like they didn't know using, I'd better rewrite that"。 不要在生产代码中这样做。抑制警告。 使这样的代码正确(并使其在面对更改时保持正确)实际上比编写使用 using 的代码 更难 抑制虚假警告(事实上,我不完全确定上面的代码 是否 正确!)。它首先破坏了进行静态代码分析的全部要点:编写可靠的代码。您应该将代码分析视为一种工具,而不是正确性的仲裁者。