Как же работает классический сценарий
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); } > >