You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行时为类的属性分配默认值?

Delphi 利用RTTI批量为类属性设置默认值

基于获取属性默认值的RTTI技术,我们可以实现一个通用例程,批量为类实例的所有属性恢复或设置其声明时的默认值。

核心实现代码

uses
  System.Rtti, System.TypInfo;

procedure SetDefaultValues(AInstance: TObject);
var
  Context: TRttiContext;
  RttiType: TRttiType;
  Prop: TRttiProperty;
  Attr: TCustomAttribute;
  DefaultValue: Variant;
  PropValue: TValue;
begin
  if not Assigned(AInstance) then Exit;

  Context := TRttiContext.Create;
  try
    RttiType := Context.GetType(AInstance.ClassType);
    for Prop in RttiType.GetProperties do
    begin
      // 遍历属性特性,查找default标记
      for Attr in Prop.GetAttributes do
      begin
        if Attr is DefaultAttribute then
        begin
          DefaultValue := (Attr as DefaultAttribute).Value;
          try
            // 转换默认值类型并赋值给属性
            PropValue := TValue.FromVariant(DefaultValue);
            if PropValue.IsEmpty then Continue;
            Prop.SetValue(AInstance, PropValue);
          except
            // 类型不匹配时跳过,避免程序崩溃
            Continue;
          end;
          Break;
        end;
      end;
    end;
  finally
    Context.Free;
  end;
end;

代码说明

  • 函数接收一个TObject实例,通过TRttiContext遍历其类的所有属性
  • 仅处理带有default特性的属性,获取特性中存储的默认值
  • 加入类型转换与异常捕获,避免因类型不匹配导致的程序异常

示例用法

先定义一个带有默认值特性的测试类:

type
  TTestClass = class(TObject)
  private
    FName: string;
    FAge: Integer;
    FActive: Boolean;
  published
    property Name: string read FName write FName default 'Unknown';
    property Age: Integer read FAge write FAge default 18;
    property Active: Boolean read FActive write FActive default True;
  end;

调用例程恢复默认值:

var
  TestObj: TTestClass;
begin
  TestObj := TTestClass.Create;
  try
    // 修改属性为非默认值
    TestObj.Name := 'Tom';
    TestObj.Age := 25;
    TestObj.Active := False;

    // 批量恢复默认值
    SetDefaultValues(TestObj);

    // 此时属性值:Name='Unknown',Age=18,Active=True
  finally
    TestObj.Free;
  end;
end;

注意事项

  • 默认只对published属性生效,若需处理public等其他可见性的属性,需在获取属性时指定过滤参数,例如RttiType.GetProperties([tkString, tkInteger], [mvPublic])
  • 对于对象、数组等复杂类型,DefaultAttribute的支持有限,这类场景需要额外编写类型适配逻辑
  • 异常处理逻辑可根据实际需求调整,比如添加日志记录便于排查问题

内容的提问来源于stack exchange,提问作者HeartWare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 13:17:16