我对 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!
最佳答案
您正在执行转换(通过执行 (Outlook.Items)oInbox.Items
)。转换意味着您将 X
类型的对象引用为 Y
类型。这在以下情况下有效:
X
在Y
的继承层次中(意味着它是Y
的父类或的子类Y
).在X
是父类的情况下,如果所讨论的对象实际上是Y
(或类型派生自Y
)Y
是由X
实现的接口(interface)类型
- 存在从
X
到Y
的显式转换定义
由于多态性,在第一种情况下进行强制转换通常 不会改变函数的行为(尽管如果更派生的类型显式隐藏了父类的实现,它可以)。 但是,我怀疑这就是您的情况; oInbox.Items
的类型是继承自 Outlook.Items
的类型,但隐藏了 Outlook.Items.Sort
的实现。通过显式转换为父类型,您将绕过新的子实现。请注意,这种技术仅在子隐藏函数而不是覆盖虚函数时有效)。
如果 X
明确实现了您打算使用的 Y
上的函数,则第二种情况可能会改变行为。通过转换为接口(interface),您明确告诉编译器您希望它将您的方法调用绑定(bind)到接口(interface)的实现,而不是类本身的普通面向公众的方法。
第三个几乎总是会改变行为,因为您得到的是完全不同的类型(因此是完全不同的对象)。
我不能说你属于这些情况中的哪一种,因为我在 Office 互操作方面没有太多具体经验,但这应该回答你的基本问题“这些有什么不同?”
关于c# - C# 中的引用和意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9214617/