CA2202, how to solve this case
.net, c#, code-analysis, fxcop
Solution
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`.
Problem
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).