3

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

请注意,我主要是一个 Java 人,并且正在帮助客户编写 C# 2.0 代码,所以我对 C# / .NET 这类事情的习语有点不熟悉。任何帮助表示赞赏。

4

2 回答 2

2

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

于 2011-03-07T13:55:20.343 回答
1

我知道这是一个老问题,但我最近不得不实现这个,所以这就是我所做的。这是一个浅层克隆,尽管需要做更多的工作,它可以变成一个深层克隆。

        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;
    }
于 2013-01-28T18:55:09.563 回答