在.NET / C中克隆或使MailMessage不可变#

时间:2011-03-07 12:50:41

标签: c# .net clone immutability system.net.mail

我正在编写一个小型库,我正在编写一些接受MailMessage对象的接口,并使用单个send方法将类返回给我,该方法将抽象出MailMessage的发送方式。我可以控制将要执行实际发送的类,但是我无法控制实现策略类。我想阻止任何实现策略类改变MailMessage。如何使MailMessage(及其包含的集合)不可变或创建它的克隆?我没有像在其他类上那样在MailMessage上看到.Clone方法。我是否必须新建一个新的MailMessage对象并在新的MailMessage上设置逐个属性?

注意,我主要是一个Java人员,正在使用C#2.0代码帮助客户端,所以我对C#/ .NET惯用语略有不熟悉。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

我认为没有快速解决方案。 MailMessage是可继承可变的,并非设计用于克隆或序列化/反序列化。如果您需要确保没有人可以更改它,请不要对其进行缓存,而是定义一个包含消息值副本的类,并在此实例之外创建新的MailMessage实例。

答案 1 :(得分:0)

我知道这是一个老问题,但我最近不得不实现这一点,所以这就是我所做的。 这是一个浅层克隆,虽然可以做更多的工作,但它可以被制作成深层克隆。

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

            MailMessage clone = new MailMessage(from, to, subject, body);
            if(cc != null) clone.CC.Add(cc);
            if(bcc !=  null) clone.Bcc.Add(bcc);

            foreach (AlternateView a in original.AlternateViews)
            {
                clone.AlternateViews.Add(a);
            }
            foreach(Attachment a in original.Attachments)
            {
                clone.Attachments.Add(a);
            }
            clone.BodyEncoding = original.BodyEncoding;
            clone.DeliveryNotificationOptions = original.DeliveryNotificationOptions;
            foreach (System.Collections.Specialized.NameValueCollection h in original.Headers)
            {
                clone.Headers.Add(h);
            }
            clone.HeadersEncoding = original.HeadersEncoding;
            clone.IsBodyHtml = original.IsBodyHtml;
            clone.Priority = original.Priority;
            clone.ReplyTo = original.ReplyTo;
            foreach (MailAddress a in original.ReplyToList)
            {
                clone.ReplyToList.Add(a);
            }
            clone.Sender = original.Sender;
            clone.SubjectEncoding = original.SubjectEncoding;

            return clone;             
    }