![]() |
Delphi-Version: XE
RTTI und Generics
Schönen guten Morgen,
bislang habe ich die RTTI nie benutzt, jetzt hätte ich mal ein wenig Zeit mich damit zu beschäftigen... Aber irgendwie scheitert es schon bei den ersten Schritten... Ich würde gerne die Objekte in einer generischen Liste durchsuchen. Allerdings klappt die Abfrage bei GetProperty nicht so richtig. Vielleicht hat jemand von euch einen Tipp für mich? :gruebel: Gefunden hätte ich ja einiges, aber immer nur bei direkter Angabe der Klasse in GetValue, aber die soll ja austauschbar sein.
Delphi-Quellcode:
TMyClass = class
private fName : String; fValue : Integer; published property Name: String read fName write fName; property Value: Integer read fValue write fValue; end; TMyList<T> = class private fList : TList<T>; public constructor Create; function Find( const Param: String; const Value: Variant ): T; function Add( const Value: T ): Integer; end; var test : TmyList<TMyClass>; begin // bisschen was hinzufügen {...} test.Find( 'Value', 100 ); {...} end; function TMyList<T>.Find( const Param: String; const Value: Variant ): T; var context : TRttiContext; typeInfo : TRttiType; prop : TRttiProperty; item : T; v : TValue; begin context := TRttiContext.Create; try typeInfo := context.GetType( System.TypeInfo(T) ); prop := typeInfo.GetProperty( Param ); for item in fList do begin v := prop.GetValue( @item ); // <- stimmt das? if v.AsVariant = Value then begin Result := item; Break; end; end; finally context.Free; end; end; |
AW: RTTI und Generics
Typisch, zuerst der Verzweiflung nahe, einen Kaffee später gefunden :wink:
Delphi-Quellcode:
trotzdem danke fürs lesen
prop.GetValue( item as TObject );
|
AW: RTTI und Generics
Zitat:
Denn wenn du diesen Cast machst, macht dein Code ja die Annahme, dass T zuweisungskompatibel zu TObject ist. Sowas drückt sollte man dem Typen-Parameter gleich mitgeben. Denn fast jede Annahme im Code sollte als Bug angesehen werden. Ich kenne mich mit Delphis IMO etwas komischen Generics-Syntax nicht so gut aus, aber ich denke, dass sieht dort so aus:
Delphi-Quellcode:
Danach sollte der Kompiler wissen, dass jedes T auch ein TObject ist. Also brauchsu keinen Cast mehr.
TMyList<T: TObject> = class
|
AW: RTTI und Generics
Du kannst mit PropInfo.PropertyType.TypeKind auch prüfen, um was für eine Eigenschaft es sich handelt.
Delphi-Quellcode:
procedure TodProp.ClearPointer(const od: Tod; p: Tod);
var Context: TRttiContext; RttiType: TRttiType; PropInfo: TRttiProperty; F: Boolean; Attr: TCustomAttribute; Value: TValue; O: TObject; PropValue: String; begin if (not Assigned(od)) or (not Assigned(p)) then Exit; od.HasNotOdPointer := True; Context := TRttiContext.Create; RttiType := Context.GetType(od.ClassType); if Assigned(RttiType) then begin for PropInfo in RttiType.GetProperties do begin F := False; for Attr in PropInfo.GetAttributes do begin if Attr is AttrOd then F := True; end; if F then begin PropValue := ''; Value := TValue.Empty; case PropInfo.PropertyType.TypeKind of // <<=============== tkClass: begin if PropInfo.IsWritable then begin od.HasNotOdPointer := False; Value := PropInfo.GetValue(od); if (not Value.IsEmpty) then begin O := Value.AsObject; if O = p then begin Value := nil; PropInfo.SetValue(od, Value); end; end; end; end; //... end; end; end; end; Context.Free; end; |
AW: RTTI und Generics
Korrekter constraint in deinem Falle wäre:
Delphi-Quellcode:
und dann kannst du direkt GetValue(item) schreiben, weil der Compiler weiß, dass item auf jeden Fall ein TObject Derivat ist.
TMyList<T: class> = class
|
AW: RTTI und Generics
Danke euch.
Aber ich denke ich gebe es wieder auf. Bekomme einen Internen Fehler (meistens F2048: AV221E0FCF-R...) nach dem anderen und verbringe mehr Zeit damit meinen Code irgendwie so umzuschreiben damit kein Fehler kommt. |
AW: RTTI und Generics
Ich lag wohl mit meinem Beitrag daneben - Du willst ja keine Eigenschaft als Objekt behandeln.
Aber vielleicht solltest Du noch prüfen, ob typeInfo und prop etwas zugewiesen wird. So weit kannst Du von einer Lösung eigentlich nicht weg sein... ;-) |
AW: RTTI und Generics
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:46 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