c# - C# 中的引用和意外结果

标签 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!

最佳答案

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

  • XY 的继承层次中(意味着它是 Y 的父类或 的子类Y).在 X 是父类的情况下,如果所讨论的对象实际上是 Y(或类型派生自 Y)
  • Y 是由X
  • 实现的接口(interface)类型
  • 存在从 XY 的显式转换定义

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

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

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

我不能说你属于这些情况中的哪一种,因为我在 Office 互操作方面没有太多具体经验,但这应该回答你的基本问题“这些有什么不同?”

关于c# - C# 中的引用和意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9214617/

相关文章:

c# - 为现有 Entity Framework 实体创建基类型(EF 模型优先)

c# - 异步 LoadImage 例程挂起

javascript - ExtJS (JavaScript) 模块设计模式最佳实践

ruby-on-rails - 传递类或字符串化的类名?

php - 在 OOP PHP 中重构代码并使用 PDO 进行 mysql 查询

rust - 将向量切片作为参数传递给函数

Swift:如何通过引用/指针来消除未知对象?

c# - .NET Core Identity as UI 取消注册

c# - 以编程方式删除克隆存储库的目录

c++ - std::list::sort 和指向元素的指针