Reputation: 880
I have an event handler which Outlook calls, passing an Outlook.MailItem as a parameter. Later, Outlook calls my handler again with a different Outlook.MailItem. How can I determine if both MailItem references refer to the same underlying Outlook email? I tried '==' and ReferenceEquals on two MailItem references that should be the same, but both == and ReferenceEquals were false.
Upvotes: 2
Views: 813
Reputation: 1161
Using Applicaton.GetObjectReference described in this post worked for me.
var ref1 = Application.GetObjectReference(mailItem1, OlReferenceType.olWeak);
var ref2 = Application.GetObjectReference(mailItem2, OlReferenceType.olWeak);
// Now you can compare the two
Upvotes: 1
Reputation: 2390
You can use MailItem.EntryID as long as the item does not get moved to a new store. 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.
If items may get moved to a new store, another solution is to wrap MailItem in your own class and have an equality comparer that checks properties that can uniquely identify an item (sender, subject, creation time, size, etc). Now you can use MyMailItem.Equals(other). See example --
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);
}
EDIT: As mentioned by Dmitry, you can also use NameSpace.CompareEntryIDs to compare two EntryIDs. You can continue to use a wrapper for MailItem, but change the Equals method to call CompareEntryIDs instead of directly comparing them. https://msdn.microsoft.com/en-us/library/office/ff864762.aspx
Upvotes: 2
Reputation: 66276
You Namespace.CompareEntryIDs passing the entry ids of the two objects. Never compare entry ids directly - multiple entry ids can refer to the same object.
Upvotes: 3