1
rttiを使用して事前設定された値を使用してクラスを作成する必要があります。値は属性から取得されます。フィールドに値を追加する必要があるときは、すべてが正常に動作します。適切なプロパティを見つけ、その属性の値が真であることを取得します。しかし、記録は操作されていません。どこが間違っているか教えてくださいフィールドにRTTIで値を記録する
program DemoGenerator;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
System.Rtti;
Type
// My attribute
DemoDataAttribute = class(TCustomAttribute)
private
FGenerator: String;
public
constructor Create(Generator: String);
published
property Generator: string read FGenerator write FGenerator;
end;
//
TSomeType = Class
private
fPhone: string;
published
[DemoData('+1800764328')]
property Phone: string read fPhone write fPhone;
End;
//
TMegaSuperClass = Class
Function Go<T: Class, constructor>: T;
End;
Procedure Test;
var
LMsc: TMegaSuperClass;
New: TSomeType;
Begin
LMsc := TMegaSuperClass.Create;
try
New := LMsc.Go<TSomeType>;
Writeln('New.Phone: ' + New.Phone);
finally
LMsc.Free;
// New.Free;
end;
End;
{ DemoDataAttribute }
constructor DemoDataAttribute.Create(Generator: String);
begin
FGenerator := Generator;
end;
{ TMegaSuperClass }
function TMegaSuperClass.Go<T>: T;
var
LContext: TRttiContext;
LClass: TRttiInstanceType;
LProp: TRttiProperty;
LAttr: TCustomAttribute;
LField: TRttiField;
begin
// Init Rtti
LContext := TRttiContext.Create;
LClass := LContext.GetType(T) as TRttiInstanceType;
Writeln('LClass: ' + LClass.ToString);
// Result
Result := T.Create;
for LProp in LClass.GetProperties do
begin
Writeln('LProp: ' + LProp.ToString);
for LAttr in LProp.GetAttributes do
begin
Writeln('LAttr: ' + LAttr.ToString);
if LAttr is DemoDataAttribute then
Begin
Writeln('Attr value: ' + DemoDataAttribute(LAttr).Generator);
// How write value?
LProp.SetValue(@Result, DemoDataAttribute(LAttr).Generator);
End;
end;
end;
end;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
Test;
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
コンソール出力:
TSomeType
プロパティ電話:文字列
DemoDataAttribute
値:1800764328
電話:このように
「ポインタ」へのキャストは必要ですが、今は確認できません。 –
キャストが必要です(別途コンパイルされません)。また、次のようにキャストすることもできます: 'TObject(Result)'とそれも機能します。コンパイラがジェネリックの現在の制約(クラスやコンストラクタの制約はTObjectの子孫を暗示すべきではないのですか?)を考慮して、そのようなキャストが必要な理由を私は本当に理解できません。 –