【问题标题】:How to compare Office interop objects for equality?如何比较 Office 互操作对象是否相等?
【发布时间】:2017-02-17 01:16:00
【问题描述】:

我有一个 Outlook 调用的事件处理程序,将 Outlook.MailItem 作为参数传递。稍后,Outlook 再次使用不同的 Outlook.MailItem 调用我的处理程序。如何确定两个 MailItem 引用是否引用相同的基础 Outlook 电子邮件?我在两个应该相同的 MailItem 引用上尝试了 '==' 和 ReferenceEquals,但 == 和 ReferenceEquals 都是错误的。

【问题讨论】:

  • 也许比较两个 MailItems 之间的属性:主题、正文和创建时间。

标签: c# com outlook vsto office-interop


【解决方案1】:

您的 Namespace.CompareEntryIDs 传递了两个对象的条目 ID。永远不要直接比较条目 id - 多个条目 id 可以引用同一个对象。

【讨论】:

  • 谢谢。 Namespace.CompareEntryIDs 是否要求两个项目都来自同一商店才能正常工作?
  • 不,它们可以来自不同的商店,如果它们来自 CompareEntryIDs,你保证会返回 false。
【解决方案2】:

您可以使用 MailItem.EntryID,只要项目没有被移动到新的商店。 https://msdn.microsoft.com/EN-US/library/office/ff866458.aspx

当在其商店中创建项目时,MAPI 商店提供程序会分配一个唯一的 ID 字符串。因此,在保存或发送 Outlook 项目之前,不会为该项目设置 EntryID 属性。当项目被移动到另一个商店时,条目 ID 会发生变化,例如,从您的收件箱移动到 Microsoft Exchange Server 公用文件夹,或从一个个人文件夹 (.pst) 文件移动到另一个 .pst 文件。 解决方案不应依赖 EntryID 属性的唯一性,除非项目不会被移动。

如果项目可能被移动到新商店,另一种解决方案是将 MailItem 包装在您自己的类中,并使用相等比较器检查可以唯一标识项目的属性(发件人、主题、创建时间、大小等)。现在您可以使用 MyMailItem.Equals(other)。见例子--

public class MyMailItem
{
    private readonly string _sender;
    private readonly int _size;
    private readonly string _subject;
    private DateTime _creationTime;

    public MyMailItem(MailItem mail)
    {
        Mail = mail;

        _sender = Mail.SenderEmailAddress;
        _size = Mail.Size;
        _subject = Mail.Subject;
        _creationTime = Mail.CreationTime;
    }

    public MailItem Mail { get; private set; }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != GetType()) return false;
        return Equals((MyMailItem)obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = (_sender != null ? _sender.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ _size;
            hashCode = (hashCode * 397) ^ (_subject != null ? _subject.GetHashCode() : 0);
            hashCode = (hashCode * 397) ^ _creationTime.GetHashCode();
            return hashCode;
        }
    }

    protected bool Equals(MyMailItem other)
    {
        return string.Equals(_sender, other._sender) && _size == other._size && string.Equals(_subject, other._subject) &&
               _creationTime.Equals(other._creationTime);
    }

编辑:正如 Dmitry 所提到的,您还可以使用 NameSpace.CompareEntryIDs 来比较两个 EntryID。您可以继续使用 MailItem 的包装器,但将 Equals 方法更改为调用 CompareEntryIDs 而不是直接比较它们。 https://msdn.microsoft.com/en-us/library/office/ff864762.aspx

【讨论】:

  • 你不应该直接比较条目ID。
  • 感谢 Dmitry,我更新了我的答案以包含您的建议。
【解决方案3】:

使用this 帖子中描述的Applicaton.GetObjectReference 对我有用。

var ref1 = Application.GetObjectReference(mailItem1, OlReferenceType.olWeak);
var ref2 = Application.GetObjectReference(mailItem2, OlReferenceType.olWeak);
// Now you can compare the two 

【讨论】:

    猜你喜欢
    • 2015-01-27
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    相关资源
    最近更新 更多