die AsType<T>
Methode von TValue
Verwenden Sie den Wert zu T
würfen
lValue := prop.GetValue(aInst);
Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(lValue.AsType<T>));
Dieses einfache Programm zeigt dies:
{$APPTYPE CONSOLE}
uses
System.RTTI;
type
TMyRecord = record
foo: Integer;
end;
TMyClass = class
function GetRec: TMyRecord;
property Rec: TMyRecord read GetRec;
function GetInt: Integer;
property Int: Integer read GetInt;
end;
function TMyClass.GetRec: TMyRecord;
begin
Result.foo := 42;
end;
function TMyClass.GetInt: Integer;
begin
Result := 666;
end;
procedure Main;
var
inst: TMyClass;
ctx: TRttiContext;
typ: TRttiType;
prop: TRttiProperty;
value: TValue;
rec: TMyRecord;
begin
inst := TMyClass.Create;
typ := ctx.GetType(TypeInfo(TMyClass));
for prop in typ.GetProperties do begin
if prop.Name='Rec' then begin
value := prop.GetValue(inst);
rec := value.AsType<TMyRecord>;
Writeln(rec.foo);
end;
end;
end;
begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
Natürlich ist dies nicht erforderlich, dass die Eigenschaft prop
der ist richtiger Typ. Wenn nicht, werden Sie einen Laufzeitfehler finden. In meinem obigen Beispiel stelle ich sicher, dass dies der Fall ist, indem ich den Namen der Eigenschaft teste, um sicherzustellen, dass ich die gewünschte Eigenschaft erhalte. Wenn Sie diesen Test entfernen, schlägt das Programm mit einer Laufzeit EInvalidCast
Fehler fehl.
Mit Blick auf Ihren Code vermute ich, dass Sie solche Fehler ziemlich wahrscheinlich sind. Es wäre für mich überraschend, wenn jede einzelne Eigenschaft von rt
vom gleichen Typ wäre.
Mit Blick auf TRTTIHelpers<T>
Ich denke nicht, dass es Ihnen in seiner jetzigen Form sehr nützlich sein wird. Zumindest wird es nicht gut mit Code interagieren, der auf RTTI basiert. Der Grund dafür ist, dass Aufrufe an TRTTIHelpers<T>
erfordern, dass Sie den Typparameter zur Kompilierzeit angeben. Aber mit RTTI-Code kennen Sie diesen Typ zur Kompilierzeit nicht. Ich vermute, dass TRTTIHelpers<T>
wahrscheinlich keine generische Klasse sein sollte, und verwenden Sie stattdessen RTTI-Typen, um Ihnen Funktionalität anzubieten, die für die Laufzeitbestimmte Typisierung flexibel ist. Dieser Rat könnte natürlich falsch sein, aber ich habe nur die kleinen Auszüge des Codes in der Frage, um mich zu führen.
Nun, das ist die Antwort auf die Frage, die Sie gestellt haben. Der Laufzeitfehler sagt Ihnen, dass, was immer in 'lValue' ist, es nicht vom Typ' T' ist. –
Was ist in lValue ist vom Typ TRTTIRecordType - wenn prop.PropertyType ist TRttiRecordType dann - und ich habe in meiner Klasse einen Datensatztyp – RBA
Ja, ein Datensatztyp. Aber nicht unbedingt der gleiche Typ wie das generische 'T', wie der Laufzeitfehler mitteilt. –