는 T
에 값을 캐스팅 TValue
의 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
가이다 것을 요구 않습니다
lValue := prop.GetValue(aInst);
Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(lValue.AsType<T>));
이 간단한 프로그램이 보여 올바른 유형. 그렇지 않으면 런타임 오류가 발생합니다. 위의 예에서 속성의 이름을 테스트하여 원하는 속성을 얻을 수 있는지 확인합니다. 해당 테스트를 제거하면 런타임에 EInvalidCast
오류로 프로그램이 실패합니다.
코드를 보면 나는 이러한 오류가 발생할 가능성이 높다고 생각합니다. rt
의 모든 속성이 동일한 유형 인 경우 나에게 놀라운 것입니다.
TRTTIHelpers<T>
에서 보니 매우 유용 할 것 같지 않습니다. 적어도 RTTI 기반의 코드와는 잘 상호 작용하지 않을 것입니다. TRTTIHelpers<T>
을 호출하는 이유는 컴파일 타임에 type 매개 변수를 제공해야하기 때문입니다. 그러나 RTTI 코드를 사용하면 컴파일 타임에 해당 유형을 알 수 없습니다. 나는 아마도 TRTTIHelpers<T>
이 제네릭 클래스가 아니어야하고 대신 RTTI 유형을 사용하여 런타임에 결정된 유형의 입력에 대해 융통성있는 기능을 제공한다고 생각합니다. 이 충고는 당연히 잘못 될 수 있지만, 나는 가이드의 질문에 단지 작은 발췌문 만 가지고있다.
글쎄, 당신이 물어 본 질문에 대한 답변입니다. 런타임 오류는'lValue'에있는 것이 모두'T' 유형이 아니라는 것을 알려줍니다. –
lValue에있는 내용은 TRTTIRecordType 유형입니다. prop.PropertyType이 TRttiRecordType 인 경우 - 내 클래스에 레코드 유형이 있습니다 – RBA
예, 레코드 유형입니다. 하지만 실행 시간 오류가 알려주므로 반드시 일반 'T'와 동일한 유형 일 필요는 없습니다. –