使用的TValue
的AsType<T>
方法將值轉換爲T
:
lValue := prop.GetValue(aInst);
Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(lValue.AsType<T>));
這個簡單的程序說明了這一點:
{$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.
當然,這並不需要的財產prop
是的正確的類型。如果沒有,那麼你會遇到運行時錯誤。在我上面的示例中,我確保通過測試屬性的名稱來確保獲得所需的屬性。如果刪除該測試,則程序將失敗,並顯示運行時間爲EInvalidCast
的錯誤。
看着你的代碼我懷疑你很可能會遇到這樣的錯誤。如果rt
的每一個財產屬於同一類型,那將是令人驚訝的。
看着TRTTIHelpers<T>
我認爲這對你目前的形式不會很有用。至少,你將無法與基於RTTI的代碼良好地交互。原因是調用TRTTIHelpers<T>
需要您在編譯時提供類型參數。但是對於RTTI代碼,在編譯時你不知道這種類型。我懷疑TRTTIHelpers<T>
應該不是泛型類,而是使用RTTI類型爲您提供功能,這對於運行時確定的鍵入來說是靈活的。這個建議當然可能是錯誤的,但是我只有這個問題中的一小段代碼來指導我。
嗯,這是你問的問題的答案。運行時錯誤告訴你,無論'lValue'是什麼,都不是'T'類型。 –
lValue中的內容是TRTTIRecordType類型 - 如果prop.PropertyType是TRttiRecordType,那麼 - 並且我在我的類中有記錄類型 – RBA
是,記錄類型。但不一定與通用'T'類型相同,因爲運行時錯誤會通知您。 –