C#中的引用和意外结果

时间:2012-02-09 16:19:13

标签: c# oop reference outlook office-automation

我对C#和Office自动化比较陌生,最近我发现自己试图获取对某人的Outlook收件箱的引用,并按接收时间对电子邮件进行排序。直到我在网络上的其他地方找到一个解决方案,其中将收件箱分配给Microsoft.Office.Interop.Outlook.Items类型的本地变量,然后对局部变量执行排序并且它可以工作时,它才能工作。然而,问题是为什么?我认为在C#对象中是引用,当你声明一个新的Outlook.Inbox引用,然后从用户的收件箱中分配它时,它只是作为指向实际电子邮件的附加指针,并不实际复制每封电子邮件到一个新的集合。所以它应该与在原始参考上调用Sort无异,对吧?显然我错了,所以我很感激解释。感谢名单!

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!

2 个答案:

答案 0 :(得分:6)

您正在执行演员表(通过执行(Outlook.Items)oInbox.Items)。转换意味着您将X类型的对象称为类型Y。这在以下情况下有效:

  • X位于Y的继承层次结构中(意味着它是Y的父类或Y的子类)。在X是父类的情况下,如果有问题的对象 Y(或从{{1}派生的类型),则强制转换只会在运行时成功})
  • Y是由Y
  • 实施的接口类型
  • XX
  • 定义了明确的转化

由于多态性,在第一种情况下通常的转换不会改变函数的行为(尽管如果更多派生类型显式隐藏了父类的实现,它也可以)。 然而,我怀疑这是你的情景; Y的类型是继承自oInbox.Items的类型,但隐藏了Outlook.Items的实现。通过显式转换为父类型,您将绕过新的子实现。请注意,这种技术仅在子隐藏函数而不是覆盖虚函数时时才有效。

如果Outlook.Items.Sort显式实现了您打算使用的X上的函数,则第二种情况可以改变行为。通过转换到接口,您明确告诉编译器您希望它将方法调用绑定到接口的实现,而不是类本身上的普通面向公共的方法。

第三个几乎总是改变行为,因为你得到的是另一种类型(因此完全不同的对象)。

我不能谈论你的这些案件中的哪一个,因为我没有特别的Office互操作经验,但这应该回答你的基本问题“这些如何不同?”

答案 1 :(得分:2)

您没有创建 Outlook.Inbox-您正在为现有收件箱创建新的参考。因此,排序实际上是在现有收件箱中完成的。