![]() |
RTTI und Array of Record
Folgende Klassen und Records habe ich (Code stark gekürzt):
Delphi-Quellcode:
Wie schaffe ich es alle Felder im Array freizugeben?
TAcField = class
private FFieldName : String; FFieldValue : String; public constructor Create(AFieldName : String); property FieldName : String read FFieldName; property FieldValue : String read FFieldValue write FFieldValue; end; TAcArticle = record Art_Desc : TAcField; Art_Qty : TAcField; end; TAcArticleArray = Array[1..5] of TAcArticle; TAc = class private FHeader : TAcField; FVersion : TAcField; FArticles : TAcArticleArray; procedure FreeFields; end; procedure TAc.FreeFields; type PAcField = ^TAcField; PAcArticleArray = ^TAcArticleArray; var LCtx : TRttiContext; LField : TRttiField; LArrayField : TRttiField; pField : PAcField; pArray : PAcArticleArray; i : Integer; begin for LField in LCtx.GetType(Self.ClassInfo).GetDeclaredFields do begin if lfield.getvalue(self).Typeinfo.Name = 'TAcField' then begin pField := PAcField(NativeInt(Self) + lField.Offset); TAcField(pField^).Free; LField.SetValue(self, nil); end; if lfield.getvalue(self).Typeinfo.Name = 'TAcArticleArray' then begin pArray := PAcArticleArray(NativeInt(Self) + lField.Offset); for i := Low(TAcArticleArray(pArray^)) to High(TAcArticleArray(pArray^)) do begin // das funktioniert zwar, aber möchte ich auch noch abstrahieren // TAcArticleArray(pArray^)[i].Art_Desc.Free; // TAcArticleArray(pArray^)[i].Art_Qty.Free; // end; // alle meine Versuche waren bislang ohne Erfolg: for LArrayField in LCtx.GetType(????TAcArticleArray(pArray^)[i]????).AsRecord.GetFields do begin pField := PAcField(NativeInt(LArrayField) + LArrayField.Offset); TAcField(pField^).Free; LArrayField.SetValue(LArrayField, nil); end; end; end; end; end; |
AW: RTTI und Array of Record
Darf man fragen, warum du hierfür RTTI verwendest? Sieht für mich so aus, als ob das Problem ohne RTTI viel einfacher und performanter zu lösen wäre.
|
AW: RTTI und Array of Record
Wie oben schon geschrieben, habe ich alles stark gekürzt. Tatsächlich handelt es sich um ca. 200 Felder, die nicht nur freigegeben werden müssen, sondern auch validiert uvm. werden müssen. Diese Klasse wird sicherlich im Laufe der Zeit immer wieder neue Felder bekommen, oder vorhandene verändert, so dass ich mir über RTTI sicherlich am wenigsten Fehlerquellen beim Programmieren einhandeln kann.
|
AW: RTTI und Array of Record
Ohne Anspruch auf Vollständigkeit, Fehlerfreiheit oder besondere Performance:
Delphi-Quellcode:
procedure FinalizeInstance(p: Pointer; typeInfo: PTypeInfo);
var ctx: TRttiContext; f: TRttiField; fieldType: TRttiType; i: Integer; arrayType: TRttiArrayType; elementType: TRttiType; obj: ^TObject; begin for f in ctx.GetType(typeInfo).GetDeclaredFields do begin fieldType := f.FieldType; case fieldType.TypeKind of tkRecord: begin FinalizeInstance(Pointer(PByte(p) + f.Offset), fieldType.Handle); FinalizeRecord(Pointer(PByte(p) + f.Offset), fieldType.Handle); end; tkArray: begin arrayType := TRttiArrayType(fieldType); elementType := arrayType.ElementType; // handle only one dim for i := 0 to arrayType.TotalElementCount - 1 do FinalizeInstance(Pointer(PByte(p) + f.Offset + (i * elementType.TypeSize)), elementType.Handle); end; tkClass: begin obj := Pointer(PByte(p) + f.Offset); FreeAndNil(obj^); end; end; end; end; |
AW: RTTI und Array of Record
Klasse, ganz herzlichen Dank!
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz