C#中的引用和意想不到的结果

问题描述:

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

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! 
+0

oInbox.Items的类型是什么?它可能是该类型重写Sort方法以具有不同的行为。通过强制转换为Outlook.Items,您可以从基类获取行为。 – cadrell0 2012-02-09 16:24:49

您正在执行演员表(通过执行(Outlook.Items)oInbox.Items)。铸造意味着您指的是类型为X的对象,类型为Y。这是有效的在下列情况:

  • XY继承层次结构中(也就是说,它要么父类的Y或子类的Y)。在X是父类的情况下,铸造将仅在运行时成功,如果在实际问题的对象是Y(或从Y派生的类型)
  • Y是受X
  • 实现的接口类型
  • 还有就是Y

由于多态性从X限定的明确的转换,在第一种情况下铸造通常不改变的功能的行为(thoug如果更多的派生类型明确隐藏了父项的实现,那么它就可以)。 然而,我怀疑这是你的情况。 oInbox.Items的类型是从Outlook.Items继承的类型,但隐藏了Outlook.Items.Sort的实现。通过显式转换为父类型,您可以绕过新的子实现。请注意,这种技术只适用于儿童隐藏函数而不是覆盖虚拟函数)

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

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

因为我没有太多具体的Office interop经验,所以我不能说出你属于哪一种情况,但是这应该回答你的基本问题:“这些情况怎么会不同?

+0

感谢您的解释。我删除了投射操作,现在有:(Outlook.Items inboxFolder = oInbox.Items;)它编译和运行就好,当我调用oInbox.Items排序它仍然无法排序,当我打电话排序在inboxFolder它确实排序正确。这很奇怪,如果我在Google – 2012-02-09 16:57:52

+0

@MikeItsMe上找不到答案,我从来不会想到为排序创建额外的参考:在这种情况下,“Outlook.Items”或者是一个接口,它是由' oInbox.Items',该类型的父类,或者可以使用*隐式*转换的类型。不过,你是对的,因为它肯定是不直观的,看起来是一个糟糕的设计选择。 – 2012-02-09 17:10:41

+0

我注意到Items属性被列为只读。这将解释为什么我无法对它们进行分类。但在C#中是否有可能通过将基础数据分配给新引用来规避只读?或者也许.Items属性在幕后做了一个克隆?感谢您继续讨论! – 2012-02-09 17:24:42

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

+0

正是。但是,为什么排序工作在新参考上,而不是原始参考上?我可以理解,如果原始收件箱是只读的,并且需要将所有项目复制到新收藏集以进行修改,但正如您所述,正在现有收件箱中执行排序。 – 2012-02-09 16:28:21

+0

啊,错过了。见@ AdamRobinson的答案。 – 2012-02-09 16:30:27