繁体   English   中英

用于枚举的Delphi RTTI SetValue

[英]Delphi RTTI SetValue for Enumerations

如何使用RTTI设置枚举字段的值?

type
  TCPIFileStatus= (fsUnknown, fsProcessed);
  TTest = class
    FStatus: TCPIFileStatus; 
  end;
      ...
  var
    Data: TTest;
    Ctx: TRttiContext;
    Status : TCPIFileStatus;
  begin
    Data := TTest.Create;
    Status := fsProcessed;
    Ctx.GetType(Data.ClassType).GetField('FStatus').SetValue(Data, Status);
  end;

我得到“无效的类类型转换”。
注意:我需要使用RTTI,因为在设计时我不会总是知道对象类型或字段名称。

您必须将TValue传递给SetValue方法尝试使用此代码:

{$APPTYPE CONSOLE}
uses
  Rtti,
  SysUtils;


type
  TCPIFileStatus= (fsUnknown, fsProcessed);
  TTest = class
    FStatus: TCPIFileStatus;
  end;

  var
    Data   : TTest;
    Ctx    : TRttiContext;
    Status : TCPIFileStatus;
    v      : TValue;
begin
  try
    Data := TTest.Create;
    try
      Status := fsProcessed;
      v:= v.From(status); 
      Ctx.GetType(Data.ClassType).GetField('FStatus').SetValue(Data, v);

      // do your stuff
    finally
       Data.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

这个问题的另一个解决方案是,如果您不知道函数的确切枚举类型,而是它的TypeInfo,则使用TValue的Make过程。

procedure Make(AValue: NativeInt; ATypeInfo: PTypeInfo; out Result: TValue); overload; static;

下面是一个示例(来自XML配置解析器):稍后用于TRTTIField / TRTTIProperty.SetValue()

function EnumNameToTValue(Name: string; EnumType: PTypeInfo): TValue;
var
  V: integer;

begin
  V:= GetEnumValue(EnumType, Name);
  TValue.Make(V, EnumType, Result);
end;

希望这对你有所帮助。

使用TValue.From泛型方法获取兼容的TValue值以传递给SetValue方法...

嗯......从单词,更好的代码中获取很难:

type
  TCPIFileStatus= (fsUnknown, fsProcessed);
  TTest = class
    FStatus: TCPIFileStatus;
  end;

procedure TForm2.Button1Click(Sender: TObject);
var
  Data: TTest;
  Ctx: TRttiContext;
  Status : TCPIFileStatus;
  AValue: TValue;
begin
  Data := TTest.Create;
  try
    Status := fsProcessed;
    Ctx.GetType(Data.ClassType).GetField('FStatus').SetValue(Data, TValue.From(Status));
    Assert(Data.FStatus = Status, 'Something wrong on assigning status trough RTTI!');
  finally
    Data.Free;
  end;
end;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM