Преобразование ссылки на интерфейс для реализации класса в Delphi 2010

Malcolm Groves, “Casting an Interface Reference to the Implementing Class in Delphi 2010”, public translation into Russian from English More about this translation.

Translate into another language.

Не все нововведения в Delphi 2010 большие и заметные. Команда потратила массу времени реализуя множество дополнительных функциональных возможностей, исправлений и улучшений. Некоторые из них могут показаться незначительными по отдельности, но они не только в целом окзывают существенное влияние, но и значительно добавляют гармоничности продукту.

Одна из возможностей Delphi 2010, которая, как мне кажется, породит массу споров - это возможность привести интерфейсную ссылку назад к типу класса, реализующего этот интерфейс.

Давайте представим, что у нас есть интерфейс IMyInterface и класс TMyClass, который реализует этот интерфейс:

IMyInterface = interface

['{7AD04980-5869-4C93-AC29-C26134511554}']

procedure Foo;

end;

TMyClass = class(TInterfacedObject, IMyInterface)

procedure Foo;

procedure Bar;

end;

Дальше, давайте представим что нам передали переменную типа IMyInterface. Что случится если мы захотим вызвать Bar? Попытка просто привести интерфейсную ссылку к типу TMyClass приведёт к ошибке компилятора.

Наиболее частое решение, которое я видел, это включить в интерфейс метод, который вернёт тип класса, но оно изничтожает ценность помещения интерфейса на первое место, привязывая интерфейс к конкретной реализации. Более того, оно отвратительно.

Что же, такие приёмы теперь не нужны.

В Delphi 2010 вы можете использовать оператор is для того, чтобы проверить реализован ли интерфейс определённым классом, и если это так, привести его к этому классу и использовать неинтерфейсные методы, свойства и т.п.

Более того, если вы попробуете привести интерфейсную ссылку к типу класса из которого она не была фактически получена, оператор as вызовет исключение EInvalidCast. При тех же условиях жесткое приведение типа вернет nil.

Теперь этот код запускается успешно:

if MyInterface is TMyClass then

TMyClass(MyInterface).Bar;

Разумеется, это нужно использовать с пониманием. Например, остаются в силе обычные предупреждения компилятора о сохранении интерфейса с подсчётом ссылок и ссылки на объект без подсчета ссылок в один и тот же экземпляр.

Original (English): Casting an Interface Reference to the Implementing Class in Delphi 2010

Translation: © TDelphiBlog, r3code, VesninAndrey .

translated.by crowd

Like this translation? Share it or bookmark!