我最近下载了Visual Studio 2013,并在我正在处理的项目上运行了代码分析.它引发了一些我正在解决的问题,但其中一个特别是关于我如何使用"使用"IDisposable语句.
这是我的代码示例:
using (MemoryStream msDecrypt = new MemoryStream(encryptedText.ToBase64Byte())) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { return srDecrypt.ReadToEnd(); } } }
我理解分析警告试图告诉我以这种方式处理多个对象可能会导致对象处置问题.
我确信在上面的例子中处理一个对象不会抛出异常.那么我应该修改我的代码还是保持原样?
据我所知,你的代码应该没有问题,我过去总是使用嵌套的using语句.
通过查看其他问题,我认为问题在于代码分析工具本身以及CA2000和CA2202规则.使用各种流和阅读器类型和using语句时经常会出现误报.
您应该忽略警告并继续,因为替代方法(例如try/finally)将产生错误代码并且您的代码有效.
我没有看到使用多个using
语句来处置对象的任何问题.嵌套的using语句很常见,代码有效.
使用不同类型的对象,如果要节省空间并提高可读性,可以使用单行语法进行嵌套:
using (MemoryStream msDecrypt = new MemoryStream(encryptedText.ToBase64Byte())) using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { return srDecrypt.ReadToEnd(); }
您遇到的问题是使用代码分析重复出现(您可以在此处找到警告的原因).然后,您可以忽略有关多个using语句的警告,因为这是误报,并且您的代码很好且有效.
您也可以通过这种方式抑制警告(感谢@Jordão),如下面这个很好的答案所述:
[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")] public void MyMethodWithUsings() { using (MemoryStream msDecrypt = new MemoryStream(encryptedText.ToBase64Byte())) using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { return srDecrypt.ReadToEnd(); } }
如果要删除警告,则必须使用块重写代码并在块中try/finally
调用Dispose()
对象的方法finally
,但这会产生可怕且不易读取的代码,正如您在此问题中看到的那样.
这是代码分析以及CA2000和CA2202的经常性问题.
您可以通过不使用using
而使用来修复这些警告try/finally/dipose
.这不推荐,因为它产生了糟糕的代码.
您的代码将起作用,只需抑制这些警告.
另请参阅/sf/ask/17360801/以获取StreamReader/Writer
基础流所有权.
对于这种类型的警告,您可以轻松忽略警告,因为它通常是误报.有关更多信息,请查看以下链接:
CA2202,如何解决这种情况
http://msdn.microsoft.com/en-us/library/ms182334.aspx
代码分析规则CA2000/CA2202
原因来自MSDN
嵌套使用语句(在Visual Basic中使用)可能会导致违反CA2202警告.如果嵌套内部using语句的IDisposable资源包含外部using语句的资源,则嵌套资源的Dispose方法将释放包含的资源.发生这种情况时,外部using语句的Dispose方法尝试再次处置其资源.
在你的情况下.可以这样使用它.所以,你应该只是压制警告.
要么
您可以通过实现Try/finally修改代码来实现抑制警告的丑陋方式.虽然,你应该真的避免这种情况.