Принципы объектно-ориентированного программирования

         

Использование динамического определения типов для выбора интерфейсов СОМ



Использование динамического определения типов для выбора интерфейсов СОМ

Как же работает классический сценарий Query Interface с точки зрения .NET-клиента, которому нужен доступ к другому интерфейсу, реализованному объектом СОМ? Все, что вам нужно, чтобы выполнить запрос QI для другого интерфейса, — это привести текущий объект к другому нужному вам интерфейсу, и — пожалуйста! — ваш запрос QI выполнен! Теперь вы готовы к вызову всех методов и свойств нужного интерфейса. Это просто.

Вся черновая закулисная работа снова достается RCW. В этом смысле она аналогична исполняющей среде Visual Basic, которая защищает разработчиков клиентов СОМ от написания любого явного кода, связанного с Query Interface. Она просто выполняет для вас запросы QI,


когда вы устанавливаете объект одного типа как объект другого ассоциированного типа.

Посмотрим на этот механизм в действии, чтобы узнать, как легко его использовать. Имея в виду наш пример, предположим, что вы хотели вызвать методы интерфейса lAirportFacilities, которые для нашего объекта СОМ реализованы другим интерфейсом. Для этого вам будет нужно привести объект Airlinelnfo к интерфейсу lAirportFacilities. Теперь вы можете вызывать все методы, которые являются частью интерфейса lAirportFacilities. Но перед приведением вы, возможно, захотите проверить, поддерживает или реализует ли имеющийся в данный момент экземпляр объекта тип интерфейса, который мы запрашиваем. Это можно сделать, вызвав метод IsInstanceOf класса System. Type. Если он возвращает true, вы знаете, что QI выполнен успешно и можно выполнить приведение. В случае приведения объекта к некоторому интерфейсу, не поддерживаемому этим объектом, генерируется исключение System.InvalidCastExcep-tion. Таким образом, RCW гарантирует, что выполняется приведение только к интерфейсам, реализованным объектом СОМ. Вот как это выглядит в написанном коде:

using System;

using System.Runtime.InteropServices;

using System.Reflection;

using AIRLINEINFORMATIONLib;

public class AirlineClient2App {

public static void Main() {

///////////////////////////////////////////////

/// Запрос интерфейса/проверка типа в период выполнения.

///////////////////////////////////////////////

try

{

Airlinelnfo objAirlinelnfo; lAirportFacilitiesInfo objFacilitiesInfo;

// Создать новый объект Airlinelnfo. objAirlinelnfo = new AirlinelnfoO;

// Вызвать метод GetAirlineTiming. String strDetails = objAirlinelnfo.GetAirlineTiming

(strAirline);

// Запросить интерфейс lAirportFacilitiesInfo. objFacilitiesInfo .=

(lAirportFacilitiesInfo)objAirlinelnfo;

//Вызвать метод интерфейса lAirportFacilitiesInfo Console.WriteLine("{0}", objFacilitiesInfo.GetlnternetCafeLocationsO);

>

catch(InvalidCastException eCast)

<

Console.WriteLine("We got an InvalidCast Exception " +

"- Message is {0}",eCast.Message); } > >



Содержание раздела