Вероятно, это не поможет, этот вопрос задавался давным-давно, но для тех, кто проверяет это в будущем ...
Возможно, вы только что опубликовали тестовый код, но ваш интерфейс должен содержать GUID, GUIDоднозначно определяет интерфейс к компилятору (Ctrl + Shift + G в Delphi 2009).
IDummy<T> = interface
['{F9EF740B-FF23-465A-A2E0-E2ACD5ABD90F}']
procedure DoSomething;
end;
Жесткое приведение обычно небезопасно.Жесткое приведение в действие допустимо только в том случае, если вы знаете, что тип объекта будет правильным.При приведении предпочтительнее проверять его тип перед приведением следующим образом ...
var
lTypeA: TTypeA;
begin
if ObjectA is TTypeA then begin
lTypeA := TTypeA(ObjectA);
end;
Еще лучше, если я выполню приведение "как", что, я думаю, вызовет исключение, если оно недопустимо.Это действительно предпочтительнее!Я написал код, который выполняет hardcast только для того, чтобы тратить часы и часы, выясняя, что на самом деле мое приведение было неверным ... Delphi не скажет вам, если вы приведете к неверному типу, тогда, когда вы позже используете объект, вы в конечном итогев целом отладочный кошмар.As вызовет исключение и покажет вам проблему в вашем коде
var
lTypeA: TTypeA;
begin
if ObjectA is TTypeA then begin
// Will raise an exception if ObjectA is not TTypeA,
// in this simple case the ObjectA is TTypeA test is redundant
lTypeA := ObjectA as TTypeA;
end;
Я бы на самом деле приводил только объекты между объектами в delphi.В Delphi есть полезная функция «поддержка», которая определяет, реализует ли объект интерфейс и возвращает ли вам экземпляр этого интерфейса.Затем вы можете использовать возвращаемую локальную переменную для выполнения любой необходимой вам функции из интерфейса
if Supports(ImplBroken, IThisBreaksIt, lObjInterface) then
begin
lObjInterface.DoSomething;
end;
Полный код ...
type
// Generic IDummy interface
IDummy<T> = interface
['{F9EF740B-FF23-465A-A2E0-E2ACD5ABD90F}']
procedure DoSomething;
end;
// Don't alias interfaces if possible
// This is a more specific version of your interface
IThisBreaksIt = interface(IDummy<Byte>)
['{76EFA371-4674-4190-8A4B-06850103C1D8}']
end;
TMyRecord = record
// I would suggest, if you can avoid it don't store interfaces
// in a record, just simple types - just my opinion, delphi doesn't stop you
Intf: IDummy<Byte>;
end;
// Remember this is interfaced, so the object only exists while refcount > 0
TDummy = class(TInterfacedObject, IDummy<Byte>)
protected
{ IDummy<T> }
// interface methods should be protected
// So ideally we refer to the interface of this object,
// not publicly available methods
procedure DoSomething;
public
end;
var
ARecord: TMyRecord;
Item: IDummy<Byte>; // Think this should be IThisBreaksIt
ImplWorks:TDummy;
ImplBroken: IThisBreaksIt;
lObjInterface: IThisBreaksIt;
begin
ARecord.Intf := TDummy.Create;
Item := ARecord.Intf;
// Nasty hard cast here - what if your interfaced object is destroyed
// before you reach this code section?
ImplWorks := TDummy(Item);
// This line compiles, buts it's really not the right way to get the interface
ImplBroken := IThisBreaksIt(ARecord.Intf);
// I believe this is the right way to get the interface for an object
if Supports(ARecord.Intf, IThisBreaksIt, lObjInterface) then
begin
lObjInterface.DoSomething;
end;
end;