Clone or make a MailMessage Immutable in .NET / C#

2.5k Views Asked by At

I'm writing a small library where I'm writing some interfaces that takes a MailMessage object and returns a class back to me with a single send method that abstracts away how that MailMessage will be sent. I have control over the class that will do the actual sending, but I don't have control over the implementing strategy classes. I'd like to prevent any implementing strategy classes from altering the MailMessage. How can I make the MailMessage (and the collections it contains) immutable or create a clone of it? I don't see a .Clone method on MailMessage itself like I do on other classes. Will I have to result to new'ing up a new MailMessage object and doing a property-by-property set on that new MailMessage?

Note, I'm mostly a Java guy and am helping a client with C# 2.0 code, so I'm slightly unfamiliar with C# / .NET idioms for things like this. Any help is appreciated.

2

There are 2 best solutions below

0
On BEST ANSWER

I don't think there is a quick solution for this. The MailMessage is inheritly mutable and isn't designed to be cloned or serialized/deserialized. If you need to make sure nobody can change it, don't cache it, but define a class that holds a copy of the values of the message and make new MailMessage instances out of this instance.

4
On

I know this is an old question, but I recently had to implement this so here's what I did. This is a shallow clone, though with a little more work it could be made into a deep clone.

        private MailMessage MailMessageShallowCopy(MailMessage original)
    {
        string to = original.To.ToString();
        string from = original.From.ToString();
        string subject = original.Subject;
        string body = original.Body;
        string cc = original.CC.ToString();
        string bcc = original.Bcc.ToString();

        MailMessage clone = new MailMessage(from, to, subject, body);
        if (!string.IsNullOrEmpty(cc))
        {
            clone.CC.Add(cc);
        }
        if (!string.IsNullOrEmpty(bcc))
        {
            clone.Bcc.Add(bcc);
        }
        foreach (AlternateView view in original.AlternateViews)
        {
            var clonedView = new AlternateView(view.ContentStream);
            foreach (var resource in view.LinkedResources)
            {
                clonedView.LinkedResources.Add(resource);
            }
            clone.AlternateViews.Add(clonedView);
        }
        foreach (Attachment attachment in original.Attachments)
        {
            clone.Attachments.Add(attachment);
        }
        clone.BodyEncoding = original.BodyEncoding;
        clone.DeliveryNotificationOptions = original.DeliveryNotificationOptions;
        foreach (NameValueCollection header in original.Headers)
        {
            clone.Headers.Add(header);
        }
        clone.HeadersEncoding = original.HeadersEncoding;
        clone.IsBodyHtml = original.IsBodyHtml;
        clone.Priority = original.Priority;
        foreach (MailAddress mailAddress in original.ReplyToList)
        {
            clone.ReplyToList.Add(mailAddress);
        }
        clone.Sender = original.Sender;
        clone.SubjectEncoding = original.SubjectEncoding;
        return clone;
    }