Навигация по деталям ссылочного равенства в контексте COM Interop - это всегда интересное упражнение.
Я бы не был знаком с деталями реализации методов Paragraph.Next()
и Paragraph.Previous()
, однако поведение, которое они демонстрируют, очень похоже на поведение коллекций на основе COM в целом в отношении создания Runtime Callable Wrapper.
Как правило, если это возможно, среда избегает создания новых экземпляров RCW в ответ на дополнительные ссылки на COM-объекты, которые уже имеют инициализированный и назначенный RCW. Если RCW уже существует для определенного указателя на IUnknown
, внутренний счетчик ссылок, поддерживаемый этим RCW, увеличивается, а затем возвращается RCW. Это позволяет платформе избежать увеличения фактического количества ссылок на COM-объекты (AddRef
).
Коллекции на основе COM, которые являются COM-объектами с управляемыми представлениями, реализующими IEnumerable
, по-видимому, генерируют новое RCW при каждом доступе к элементу, даже если к этому элементу уже был получен доступ во время сеанса.
Например:
Word.Document document = Application.ActiveDocument;
Paragraphs paragraphs = document.Paragraphs;
Paragraph first = paragraphs[1];
Paragraph second = paragraphs[1];
bool thisIsFalse = (first == second);
Если вы хотите выполнить какую-либо проверку «ссылочного равенства», вам нужно выйти из коллекции на основе COM, в частности, в вашем случае: объект Paragraphs
. Вы можете сделать это, просто взяв детей и сохранив их в своей собственной, полностью управляемой и предсказуемой коллекции, например:
List<Paragraph> niceParagraphs = paragraphs.Cast<Paragraph>().ToList();
Хотя использование LINQ с COM Interop может выглядеть немного страшно (если это не так ... это действительно так!) Я вполне уверен, что приведенный выше код безопасен и не оставит никаких висящих ссылок, или что-нибудь еще противное. Однако я не проверил приведенный выше код исчерпывающе.
Не забудьте правильно освободить эти ресурсы, когда вы закончите с ними, по крайней мере, если ваши требования требуют такого уровня осторожности.