Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

references in C# and unexpected results

I'm relatively new to C# and Office automation and recently I found myself trying to obtain a reference to someone's Outlook inbox and sorting the emails by Received time. It wasn't working until I found a solution elsewhere on the web where the Inbox is assigned to a local variable of type Microsoft.Office.Interop.Outlook.Items and then the sort is performed on the local variable and it works. The question, however, is why? I thought that in C# objects are references and when you declare a new Outlook.Inbox reference and then assign it the Items from the user's Inbox, it simply serves as an additional pointer to the actual emails, and DOES NOT actually copy each of the emails to a new collection. So it should be no different than calling Sort on the original reference, right? Obviously I'm wrong, so I'd appreciate an explanation. Thanx!!

using Outlook = Microsoft.Office.Interop.Outlook;    
...
Outlook.Folder oInbox = (Outlook.Folder)oApp.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);

oInbox.Items.Sort("[Received]", true); //this doesn't produce expected results
Outlook.Items inboxFolder = (Outlook.Items)oInbox.Items;
inboxFolder.Sort("[Received]", true);  //this DOES sort the items!
like image 713
public wireless Avatar asked Feb 21 '23 13:02

public wireless


1 Answers

You're performing a cast (by doing (Outlook.Items)oInbox.Items). Casting means that you're referring to an object of type X as type Y. This is valid in the following scenarios:

  • X is within the inheritance hierarchy of Y (meaning that it's either a parent class of Y or a child class of Y). In the case where X is a parent class, the cast will only succeed at runtime if the object in question actually is Y (or a type derived from Y)
  • Y is an interface type that is implemented by X
  • There is an explicit conversion defined from X to Y

Because of polymorphism, casting in the first case usually doesn't change the behavior of functions (though it can if the more derived type explicitly hides the implementation of the parent). My suspicion, however, is that this is your scenario; the type of oInbox.Items is a type that inherits from Outlook.Items but hides the implementation of Outlook.Items.Sort. By explicitly casting to the parent type, you're bypassing the new child implementation. Note that this sort of technique only works when the child hides the function rather than overriding a virtual function).

The second case can change behavior if X explicitly implements the function(s) on Y that you're intending to use. By casting to the interface, you're explicitly telling the compiler that you want it to bind your method call to the implementation for the interface rather than the ordinary public-facing method on the class itself.

The third almost always changes behavior, since you're getting a different type (and thus an entirely different object) altogether.

I can't speak as to which one of these cases yours falls into, since I don't have much experience with Office interop specifically, but this should answer your basic question of "how can these be different?"

like image 54
Adam Robinson Avatar answered Mar 08 '23 16:03

Adam Robinson