C# 中的引用和意外结果

本文关键字:意外 结果 引用 | 更新日期: 2023-09-27 18:24:00

我对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!

C# 中的引用和意外结果

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

  • X 位于 Y 的继承层次结构中(这意味着它是 Y 的父类或 Y 的子类(。在 X 是父类的情况下,只有在相关对象实际上是Y(或从 Y 派生的类型(时,强制转换才会在运行时成功
  • Y 是由 X 实现的接口类型
  • 定义了从XY的显式转换

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

如果X在打算使用的Y上显式实现函数,则第二种情况可能会更改行为。通过强制转换为接口,您可以显式告诉编译器您希望它将方法调用绑定到接口的实现,而不是类本身上的普通面向公众的方法。

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

我不能说你属于这些情况中的哪一种,因为我对Office互操作没有太多经验,但这应该回答你的基本问题"这些怎么会不同?

您不是在创建新的 Outlook.Inbox,而是在创建对现有收件箱的新引用 因此,排序实际上是在现有收件箱上完成的。