Search code examples
c#.netidisposable

Objects implementing IDisposable using another IDisposable


I try to develop an application in C# and have some concerns with MailMessage object:

it implements IDisposable interface, so I use it within using statement. So it implicitly calls Dispose method after. Now, using that object I need to add attachments, which I have converted to byte[] object and I add them as stream. Here's part of code to have better view:

using(MailMessage message = new MailMessage("john.smith@gmail.com"){
    MemoryStream stream;
    //here I pass byte array to the stream and create an attachemnt
    message.Attachments.Add(new Attachment(stream, "name.xyz"));

    using(SmtpClient client = new SmtpClient("server.com", port))
    {
        // send message
    }
}

Now, I have one resource unmanaged: Stream object. I can't close it (so can't call Dispose method) right after setting attachments, because I'd get an error when sending message, because it uses the stream while sending.

So, I need to get rid of it later, which I do after sending. That's the code in second using:

try
{
    client.Send(messgae);
}
finally
{
    if(stream != null)
        stream.Dispose();
}

Now the question: Dispose method of MailMesssage frees all resources used by that object. My Stream object is one of the resources, isn't it? So, when using(MailMessage... terminates it should manage also my Stream object, shouldn't it? So I wouldn't need to dispose of my Stream object manually.

EDIT:

Suggested approach:

using(MailMessage message = new MailMessage("john.smith@gmail.com"){
    using(MemoryStream stream = ...)
    {
        //here I pass byte array to the stream and create an attachemnt
        message.Attachments.Add(new Attachment(stream, "name.xyz"));

        using(SmtpClient client = new SmtpClient("server.com", port))
        {
            // send message
        }
    }
}

But the questions stays: MailMessage uses this Stream - so, do we still need to manage Stream on our own?


Solution

  • From the reference documentation you don't need to when you are using using.

    Mail Message disposes Attachment Collection, which then disposes all its attachements.


    Regarding, should we take or rely on this approach then I totally agree with Zohar on

    Disposing of an IDisposable should be expressed in your code, either by calling Dispose explicitly or with the using statement.