如何在运行时为类的属性分配默认值?
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
相关产品推荐
相关产品推荐

