2
votes

I have a class like so...

public class Class1
{
    public Class1()
    {
        byte[] plainText = new byte[1024];
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                csEncrypt.Write(plainText, 0, plainText.Length);
                csEncrypt.FlushFinalBlock();
                csEncrypt.Flush();
                encrypted = msEncrypt.ToArray();
            }
        }
    }
    public ICryptoTransform encryptor { get; set; }
    public byte[] encrypted { get; set; }
}

Code analysis throws the following warning. Do not dispose objects multiple times.

http://msdn.microsoft.com/en-us/library/ms182334.aspx.

I am not able to comprehend this line in the article above [Example section]... "Nested using statements (Using in Visual Basic) can cause violations of the CA2202 warning. If the IDisposable resource of the nested inner using statement contains the resource of the outer using statement, the Dispose method of the nested resource releases the contained resource. When this situation occurs, the Dispose method of the outer using statement attempts to dispose its resource for a second time."

IL for this code

1
The CryptoStream might already be disposing the MemoryStream. - leppie
leppie is right, but there is no harm in disposing twice, because it won't throw an exception. Your syntax is correct and in my opinion, the CryptoStream should not touch the Dispose method of the injected stream. I would argue to supress the warning. - Silvermind
@Silvermind I agree with you, this is counter intuitive. Why would I expect CryptoStream to dipose its base stream? I may need it for later use. I believe this is a bad design which msft chosen for IDisposable. - Sriram Sakthivel
It's not a bad design for IDisposable, it's a debatable design of the CryptoStream. Similar for TextReader, BinaryReader et al. - Henk Holterman

1 Answers

3
votes

It states that when you call Dispose on a resource, it will dispose all the resource which it holds. So the inner resource here csEncrypt which holds the outer resource msEncrypt on csEncrypt.Dispose it will have disposed msEncrypt as well.

Later msEncrypt.Disopse is called, so Code Analysis warns you about calling Dispose multiple times.