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

这个问题在您看来可能与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); 

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

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

真的,真的,压制警告。 警告是错误的。 没关系。 🙂

谷歌搜索“嵌套使用CA2202”,你会发现有关此问题的数十个stackoverflow和MSDN论坛post。 https://www.google.com/search?q=ca2202+nested+using

最终,CA2202和CA2000受到限制,因为它们无法理解嵌套的IDisposable对象的行为。 可以将某些流配置为使基础流保持打开状态,但通常它们不会。 抑制确实是正确的解决方案。 问题是你正在努力成为一个好公民,所以你正试图遵守你给出的警告。 但静态分析并不足以处理这个问题。