如何比较 Office 互操作对象的相等性?

How to compare Office interop objects for equality?

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

您可以使用 MailItem.EntryID,只要商品不被转移到新商店即可。 https://msdn.microsoft.com/EN-US/library/office/ff866458.aspx

A MAPI store provider assigns a unique ID string when an item is created in its store. Therefore, the EntryID property is not set for an Outlook item until it is saved or sent. The Entry ID changes when an item is moved into another store, for example, from your Inbox to a Microsoft Exchange Server public folder, or from one Personal Folders (.pst) file to another .pst file. Solutions should not depend on the EntryID property to be unique unless items will not be moved.

如果项目可能会转移到新商店,另一种解决方案是将 MailItem 包装在您自己的 class 中并有一个相等比较器来检查可以唯一标识项目的属性(发件人、主题、创建时间、尺寸等)。现在您可以使用 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

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

使用 Applicaton.GetObjectReference described in this post 对我有用。

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