Can anybody tell me how to remove all CA2202 warnings from the following code?

public static byte[] Encrypt(string data, byte[] key, byte[] iv)
{
    using(MemoryStream memoryStream = new MemoryStream())
    {
        using (DESCryptoServiceProvider cryptograph = new DESCryptoServiceProvider())
        {
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write))
            {
                using(StreamWriter streamWriter = new StreamWriter(cryptoStream))
                {
                    streamWriter.Write(data);
                }
            }
        }
        return memoryStream.ToArray();
    }
}

Warning 7 CA2202 : Microsoft.Usage : Object 'cryptoStream' can be disposed more than once in method 'CryptoServices.Encrypt(string, byte[], byte[])'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 34

Warning 8 CA2202 : Microsoft.Usage : Object 'memoryStream' can be disposed more than once in method 'CryptoServices.Encrypt(string, byte[], byte[])'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 34, 37

You need Visual Studio Code Analysis to see these warnings (these are not c# compiler warnings).

推荐答案

This compiles without warning:

    public static byte[] Encrypt(string data, byte[] key, byte[] iv)
    {
        MemoryStream memoryStream = null;
        DESCryptoServiceProvider cryptograph = null;
        CryptoStream cryptoStream = null;
        StreamWriter streamWriter = null;
        try
        {
            memoryStream = new MemoryStream();
            cryptograph = new DESCryptoServiceProvider();
            cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write);
            var result = memoryStream;              
            memoryStream = null;
            streamWriter = new StreamWriter(cryptoStream);
            cryptoStream = null;
            streamWriter.Write(data);
            return result.ToArray();
        }
        finally
        {
            if (memoryStream != null)
                memoryStream.Dispose();
            if (cryptograph != null)
                cryptograph.Dispose();
            if (cryptoStream != null)
                cryptoStream.Dispose();
            if (streamWriter != null)
                streamWriter.Dispose();
        }
    }

Edit in response to the comments: I just verified again that this code does not generate the warning, while the original one does. In the original code, CryptoStream.Dispose() and MemoryStream().Dispose() are actually called twice (which may or may not be a problem).

The modified code works as follows: references are set to null, as soon as responsibilty for disposing is transferred to another object. E.g. memoryStream is set to null after the call to CryptoStream constructor succeeded. cryptoStream is set to null, after the call to StreamWriter constructor succeeded. If no exception occurs, streamWriter is disposed in the finally block and will in turn dispose CryptoStream and MemoryStream.

.net相关问答推荐

尽管有`disable`注释,但未 suppress Pylint语法错误

dotnet 8 web api在部署到docker后无法工作

在 Invoke() 中运行时,跨线程操作对表单控件无效 - .NET

查询 MongoDb 中嵌入式文档中的一个字段,该字段抛出调用运算符的左侧必须是对持久属性的直接访问

xunit Assert.ThrowsAsync() 不能正常工作?

Gacutil.exe 成功添加程序集,但在资源管理器中无法查看程序集.为什么?

在 C# 中将字节数组保存为磁盘上的文件的最有效方法是什么?

每第 N 个字符/数字拆分一个字符串/数字?

如何在 C# 4.0 中使任务进入睡眠状态(或延迟)?

如何在 C# 中创建 Word 文档?

SubscribeOn 和 ObserveOn 有什么区别

HashSet 是否保留插入顺序?

无法在 Windows 10 上安装 Windows SDK 7.1

是否有可用的 WPF 备忘单?

如何对 LINQ to XML 中的元素进行深层复制?

如何在 WebBrowser 控件中注入 Javascript?

使用 LINQ 搜索树

忽略 LINQ to XML 中的命名空间

如何将 .NET 应用程序编译为本机代码?

您可以将 Microsoft Entity Framework 与 Oracle 一起使用吗?