2016-03-26 13 views
1

Delphi Generic Classes için yeni. Uygulama kodunda genel sınıfları nasıl kullanacağımı anlamıyorum.Delphi Genel Şablon sınıfları Kullanım Derleme Hatası

: Aşağıdaki hatayı olsun Method1)

var z:TDataArray<TDataElement>; 
    z:=TDataArray<TDataElement>.Create(); 

:

Type TDataElement = class(TObject) 
    protected 
    Procedure SetName(sNewValue:String); virtual; 
    private 
    m_sName:String; 
    published 
    property sName:String read m_sName write SetName; 
end; 

Type TDataArray<T : TDataElement> = class(TObject) 
    public 

    function Find(dtElement:T):integer; 
    Procedure Add(dtElement:T); 
    private 
    m_vContainer : array of T; 
    protected 
    Function GetData(Index:integer):T; virtual; 
    Procedure SetData(Index:integer; NewValue:T); virtual; 
    public 
    property vData[Index: Integer]: T read GetData write SetData; 
end; 

implementation 

function TDataArray<T>.Find(dtElement:T):integer; 
var i:integer; 
begin 
    Result:=-1; 
    for i := 0 to high(m_vContainer) do 
    if (m_vContainer[i] <> NIL)and(m_vContainer[i] = dtElement) then 
    begin 
     Result:=i; 
     exit; 
    end; 
end;  
..... 

Aşağıdaki kodu gibi Jenerik Sınıfların örneklerini oluşturmayı deneyin: İşte kodudur

E2010 Uyumsuz türler: 'TDataElement' ve 'TDataElement' sınıfı

Eğer 2. yöntemini yaparsam başka garip bir hata alıyorum: Yöntem 2) tip TDataElementClass = TDataElement sınıfı;

var z:TDataArray<TDataElementClass>; 

F2084 İç Hata: Yanlış yapıyorum I8230

? Bir dosya

System.SysUtils,Classes, 
    dtArray_unit in 'D:\VisionBot\Software\VisionBot\GUI\Units\dtArray_unit.pas'; 


Type TDataElement = class(TObject) 
    protected 
    Procedure SetName(sNewValue:String); virtual; 
    private 
    m_sName:String; 
    published 
    property sName:String read m_sName write SetName; 
end; 

Type TDataArray<T : TDataElement> = class(TObject) 
    public 

    function Find(dtElement:T):integer; overload; 

    Procedure Add(dtElement:T); 
    private 

    m_vContainer : array of T; 
    protected 
    Function GetData(Index:integer):T; virtual; 
    Procedure SetData(Index:integer; NewValue:T); virtual; 
    public 
    property vData[Index: Integer]: T read GetData write SetData; 
end; 

type 
    TDerivedDataElement = class(TDataElement) 
    end; 

var 
    z2: TDataArray<TDerivedDataElement>; 


//------------------------------------------------------------------------------ 
Procedure TDataElement.SetName(sNewValue:String); 
begin 
    self.m_sName:=sNewValue; 
end; 
//------------------------------------------------------------------------------ 
//------------------------------------------------------------------------------ 
//------------------------------------------------------------------------------ 
function TDataArray<T>.Find(dtElement:T):integer; 
var i:integer; 
begin 
    Result:=-1; 
    for i := 0 to high(m_vContainer) do 
    if (m_vContainer[i] <> NIL)and(m_vContainer[i] = dtElement) then 
    begin 
     Result:=i; 
     exit; 
    end; 
end; 
//------------------------------------------------------------------------------ 
Function TDataArray<T>.GetData(Index:integer):T; 
begin 
    Result:=NIL; 
    if Index < 0 then exit else 
    if Index > high(Index) then exit else 
    Result:=self.m_vContainer[Index]; 
end; 
//------------------------------------------------------------------------------ 
Procedure TDataArray<T>.Add(dtElement:T); 
begin 
    SetLength(self.m_vContainer,Length(m_vContainer)+1); 
    m_vContainer[High(m_vContainer)]:=T; 
end; 
//------------------------------------------------------------------------------ 
Procedure TDataArray<T>.SetData(Index:integer; NewValue:T); 
begin 
    if Index < 0 then exit else 
    if Index > high(Index) then exit else 
    self.m_vContainer[Index]:=T; 

end; 
//------------------------------------------------------------------------------ 


begin 
    try 

    z2:= TDataArray<TDerivedDataElement>.Create(); 

    readln; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 
+0

Bu, metasınıfları sınıflarla karıştırıyor gibi görünüyor. Z nasıl bildirilir? 'T: TDataElement' Eğer TDataElement' sınıfı ya da herhangi bir soyundan sınıfı 'ile,' t 'yerine, ancak TDataElement' metaclass (TDataElement' arasında' sınıfı)' ile anlamına gelir. –

+0

Metasınıflar ve sınıflar arasındaki farkı hiç bilmiyorum. Küçük bir düzenleme yaptım. Bunu bile yaparım: var z: TDataArray ; z: = TDataArray .Create(); Hata alıyorum (ilk yöntem) – user558126

+0

* Dahili hata * 'nın her zaman derleyicide bir hata olduğunu unutmayın. Bu, yanlış bir şey yapmamanız anlamına gelir, derleyici muhtemelen biraz kenar durumunun ne olduğuyla karşılaştı ve bunu kaldıramıyor. Bazen kodun yeniden düzenlenmesi veya ara sonuçların ad-hoc bildirimleri yerine değişkenlere bildirilmesi veya bildirilmesi yardımcı olabilir, ancak bu garanti edilmez. Unutmayın ki bir iç hata sizin hatanız değildir. –

cevap

4
var 
    z: TDataArray<TDataElementClass>; 

sorun,

Bütün kaynak kodu TDataElementClassTDataElement türetilmiş bir sınıf olmadığıdır.

şu geçerli olacaktır:

var 
    z: TDataArray<TDataElement>; 

Ya da bu: Kodunuzda

type 
    TDerivedDataElement = class(TDataElement) 
    end; 

var 
    z: TDataArray<TDerivedDataElement>; 

Asistan

type 
    TDataElementClass = class of TDataElement; 

var TDataElementClass bir metaclass olduğunu.

  • tip TDataElement bir değişken, örneğin tip TDataElement veya TDataElement türetilen herhangi bir sınıfın bir örneği tutabilir.
  • tip TDataElementClass bir değişken TDataElement veya TDataElement türetilmiş herhangi bir sınıf olması gereken bir tip, tutabilir.

TDataArray<TDataElement> kullanımının bir derleyici hatasına yol açtığını iddia ediyorsunuz, ancak bu doğru değil.T bir tür olduğu için bu başarısız

m_vContainer[High(m_vContainer)]:=T; 

:

Procedure TDataArray<T>.Add(dtElement:T); 
begin 
    SetLength(self.m_vContainer,Length(m_vContainer)+1); 
    m_vContainer[High(m_vContainer)]:=T; 
end; 

hatalı hat burada: Bu kod göstermek Düzenlemenizle olarak

type 
    TDataElement = class 
    end; 

type 
    TDataArray<T: TDataElement> = class 
    public 
    function Find(dtElement: T): Integer; 
    private 
    m_vContainer: array of T; 
    end; 

function TDataArray<T>.Find(dtElement: T): Integer; 
begin 
    for Result := 0 to high(m_vContainer) do 
    if (m_vContainer[Result] <> nil) and (m_vContainer[Result] = dtElement) then 
     exit; 
    Result := -1; 
end; 

var 
    arr: TDataArray<TDataElement>; 

begin 
    arr := TDataArray<TDataElement>.Create; 
end. 

: Bu derleme programı düşünün bir örnek yerine. Bence demek istediniz:

m_vContainer[High(m_vContainer)]:=dtElement; 
+0

Delphi XE 3'te ikinci yöntem çalıştı TDerivedDataElement 'sınıfı – user558126

+1

Bu iddia gerçekler tarafından desteklenmez.Tüm kodunuzu göstermediniz.Programı derlemeyi engelleyen bir kodu atladınız.Programı tamamlayacak tam bir program ekledim. –

+0

Test ettim ..? Ben indentified – user558126