mj2*_*008 5 delphi rtti delphi-xe
在这里的问题中,示出了用于创建与SetValue一起使用的兼容TValue的方法.我正在尝试制作一个通用版本,使用RTTI将类存储到INI文件中.这是我的减少代码:
procedure TMyClass.LoadRTTI(xObject: TObject);
var
LContext: TRttiContext;
LClass: TRttiInstanceType;
xField : TRttiField;
szNewValue : String;
xValue : TValue;
begin
LContext := TRttiContext.Create;
LClass := LContext.GetType(xObject.ClassType) as TRttiInstanceType;
for xField in LClass.GetDeclaredFields do
begin
szNewValue := IniFile.ReadString(szSection, xField.Name, '');
if szNewValue <> '' then // emumerated will be '0' (zero) as that is what GetValue.AsString returns
begin
case xField.FieldType.TypeKind of
tkEnumeration: xValue := StrToIntDef(szNewValue, xField.GetValue(xObject).AsOrdinal);
end;
xField.SetValue(xObject, xValue); // FAILS HERE with 'Invalid calss typecast
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
在引用的答案中,解决方案是使用TValue.From()方法获取值,但这似乎需要适当类型的变量.我没有这样的类型,因为我的代码不知道它是什么.
我正在寻找一个通用方法的例子来从RTTI获取字符串中的值,然后再将其重新放回.我还没有找到一个很好的教程来解决这个问题.
在TValue确定值之前,必须先获取要设置的实例,然后使用该GetEnumValue函数将字符串转换为枚举值
试试这段代码:
procedure TMyClass.LoadRTTI(xObject: TObject);
var
LContext: TRttiContext;
LClass: TRttiInstanceType;
xField : TRttiField;
szNewValue : String;
xValue : TValue;
begin
LContext := TRttiContext.Create;
LClass := LContext.GetType(xObject.ClassType) as TRttiInstanceType;
for xField in LClass.GetDeclaredFields do
begin
szNewValue := IniFile.ReadString(szSection, xField.Name, '');
if szNewValue <> '' then // emumerated will be '0' (zero) as that is what GetValue.AsString returns
begin
case xField.FieldType.TypeKind of
tkEnumeration:
begin
//get the instance to the TValue to set
xValue:=xField.GetValue(xObject);
//convert the data to a valid TValue
xValue:=TValue.FromOrdinal(xValue.TypeInfo,GetEnumValue(xValue.TypeInfo,szNewValue));
end;
end;
//assign the new value from the TValue
xField.SetValue(xObject, xValue);
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
这是一些示例代码,显示了如何执行此操作:
var
V : TValue;
OrdValue : Integer;
C : TRttiContext;
F : TRttiField;
lTypeInfo : PTypeInfo;
begin
// Pick a Enumerated Field
F := C.GetType(TForm).GetField('FFormStyle');
// Get the TypeInfo for that field
lTypeInfo := F.FieldType.Handle;
// Setting TValue from an Enumeration Directly.
V := TValue.From(FormStyle);
ShowMessage(V.ToString);
// Setting TValue from the ordinal value of a Enumeration
OrdValue := ord(FormStyle);
V := TValue.FromOrdinal(lTypeInfo,OrdValue);
ShowMessage(V.ToString);
// Setting TValue from the String Value of an enumeration.
OrdValue := GetEnumValue(lTypeInfo,'fsStayOnTop');
V := TValue.FromOrdinal(lTypeInfo,OrdValue);
ShowMessage(V.ToString);
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3801 次 |
| 最近记录: |