如何满足CA2202(不要多次丢弃对象)

cil*_*ler 3 c# code-analysis

这个问题在您看来可能与CA2202重复,如何解决这个具有公认答案的案例.但是你可能会意识到,接受的答案有5个基于质量差的投票.此外,任何其他投票的答案实际上并不能解决问题.他们中的大多数人都解释了如何压制规则或辩论这条规则是多么错误以及为什么我们应该忽略它.由于那个规则存在,应该有一种方法来满足它,我正在寻找社区支持来解决这个问题.

我试图弄清楚如何在以下代码中满足CA2202.我理解这里的问题是,using语句还配置了encryptedStream对象.但是如果我删除了finally部分,它就会开始抛出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);
Run Code Online (Sandbox Code Playgroud)

Jer*_*ert 6

这是对您的问题的字面答案,因为它不会在不抑制它们的情况下发出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);
Run Code Online (Sandbox Code Playgroud)

但任何值得他们盐的开发者都应该看看这个并且去"嗯,就像他们不知道using,我最好重写一下".不要在生产代码中执行此操作.取消警告.获得这样的代码是正确的(并且在面对变化时保持正确)实际上比编写用于抑制虚假警告的代码更难using(事实上​​,我不完全确定上面的代码正确的!).它首先打破了静态代码分析的全部要点:编写可靠的代码.您应该将代码分析视为一种工具,而不是正确性的仲裁者.