2015-03-18 13 views
8

Bir sınıf tipi (T) ve bir arabirim türü (I) kabul eden ve nesneye (I) bir arabirim (I) döndüren bir işlev yazdım. İşte kod. hafıza sızıntıları ya da diğer istenmeyen beklendiği gibiArabirim nesnesini oluşturmak için Generic'leri kullanma

interface 

function CreateObjectInterface<T: Class, constructor; I: IInterface>(
    out AObject: TObject): I; 

...

implementation 

function TORM.CreateObjectInterface<T, I>(out AObject: TObject): I; 
begin 
    AObject := T.Create; 

    if not Supports(AObject, GetTypeData(TypeInfo(I))^.Guid, Result) then 
    begin 
    AObject.Free; 
    AObject := nil; 

    raise EORMUnsupportedInterface.CreateFmt(
     'Object class "%s" does not support interface "%s"', 
     [AObject.ClassName, GUIDToString(GetTypeData(TypeInfo(I))^.GUID)] 
    ); 
    end; 
end; 

fonksiyon çalışır.

Aynı sonuca ulaşmak için başka yollar var mı?

+5

Ben bu emin değilim soru burada uygun. Belki de kod incelemesi daha iyi bir site olacaktır. Son sorunuz kesinlikle görüşe dayalı. İlk iki soru. 1. Evet, sorun değil. 2. Hayır, sorun yok. –

+0

Son soruyu "aynı sonucu elde etmenin başka yolları var mı?" –

+0

@LURD - – norgepaul

cevap

14

Bu kodda bir hata var. Destekler, nesne örneğini IUnknown destekliyorsa ancak istediğiniz arabirimi desteklemez.

Basit gösteri: En

type 
    IFoo = interface 
    ['{32D3BE83-61A0-4227-BA48-2376C29F5F54}'] 
    end; 

var 
    o: TObject; 
    i: IFoo; 
begin 
    i := TORM.CreateObjectInterface<TInterfacedObject, IFoo>(o); // <- boom, invalid pointer 
end. 

T için IInterface veya IUnknown olarak ek sınırlamayı koymak. Veya daha önce yok edilen bir örneği imha etmediğinizden emin olun. Eğer ben sınıfta bir Supports çağrıyla gider (sınıf arayüzünü ama QueryInterface döner bunu uygulamıyor yerde) QueryInterface uygulamaları dinamik desteklemek istemiyorsan

:

function TORM.CreateObjectInterface<T, I>(out AObject: TObject): I; 
begin 
    if not Supports(TClass(T), GetTypeData(TypeInfo(I))^.Guid) then 
    raise EORMUnsupportedInterface.CreateFmt(
     'Object class "%s" does not support interface "%s"', 
     [AObject.ClassName, GUIDToString(GetTypeData(TypeInfo(I))^.GUID)] 
    ); 

    AObject := T.Create; 
    Supports(AObject, GetTypeData(TypeInfo(I))^.Guid, Result); 
end; 
+0

İyi yakalama Stefan. – norgepaul

İlgili konular