ссылки на C # и неожиданные результаты - PullRequest
4 голосов
/ 09 февраля 2012

Я относительно новичок в C # и автоматизации Office, и недавно я обнаружил, что пытаюсь получить ссылку на чей-либо почтовый ящик Outlook и сортировать электронные письма по времени получения. Это не работало, пока я не нашел решение в другом месте в Интернете, где папка «Входящие» назначается локальной переменной типа Microsoft.Office.Interop.Outlook.Items, а затем выполняется сортировка по локальной переменной, и она работает. Вопрос, однако, почему? Я думал, что в C # объекты являются ссылками, и когда вы объявляете новую ссылку Outlook.Inbox и затем назначаете ей элементы из папки «Входящие» пользователя, она просто служит дополнительным указателем на фактические электронные письма, и фактически НЕ копирует каждое электронное письмо в новую коллекцию. Так что это не должно отличаться от вызова Sort по исходной ссылке, верно? Очевидно, я не прав, поэтому я был бы признателен за объяснение. Thanx !!

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 ]

6 голосов
/ 09 февраля 2012

Вы выполняете приведение (выполняя (Outlook.Items)oInbox.Items).Приведение означает, что вы ссылаетесь на объект типа X как тип Y.Это допустимо в следующих сценариях:

  • X находится в иерархии наследования Y (это означает, что это либо родительский класс Y, либо дочерний класс Y),В случае, когда X является родительским классом, приведение будет успешным только во время выполнения, если рассматриваемый объект на самом деле равен Y (или тип, производный от Y)
  • Y - это тип интерфейса, который реализуется с помощью X
  • Существует явное преобразование, определенное из X в Y

Из-за полиморфизма приведениепервый случай обычно не меняет поведение функций (хотя это может произойти, если более производный тип явно скрывает реализацию родителя). Однако я подозреваю, что это ваш сценарий;тип oInbox.Items - это тип, который наследуется от Outlook.Items, но скрывает реализацию Outlook.Items.Sort.При явном приведении к родительскому типу вы обходите новую дочернюю реализацию.Обратите внимание, что этот вид техники работает только тогда, когда дочерний элемент скрывает функцию, а не переопределяет виртуальную функцию) .

Второй случай может изменить поведение, если X явно реализуетфункция (и) на Y, которую вы собираетесь использовать.Приведя к интерфейсу, вы явно указываете компилятору, что вы хотите, чтобы он связывал ваш вызов метода с реализацией для интерфейса, а не с обычным общедоступным методом в самом классе.

Третий почтивсегда меняет поведение, так как вы получаете совершенно другой тип (и, следовательно, совершенно другой объект ).

Я не могу говорить о том, к какому из этих случаев относится ваш случай,поскольку у меня нет особого опыта взаимодействия с Office, но это должно ответить на ваш основной вопрос «как они могут отличаться?»

2 голосов
/ 09 февраля 2012

Вы не создаете новый Outlook.Inbox - вы создаете новую ссылку на существующий почтовый ящик.Таким образом, сортировка фактически выполняется на месте существующего почтового ящика.

...