delphi – 基于非约束泛型类型创建对象实例
发布时间:2020-12-15 04:25:46 所属栏目:大数据 来源:网络整理
导读:我有无约束的通用类型Atomic,它实现一个初始化器(在我的 previous question中的细节). type AtomicT = class type TFactory = reference to function: T; class function Initialize(var storage: T; factory: TFactory): T; end; 现在我想编写简化的初始化
我有无约束的通用类型Atomic,它实现一个初始化器(在我的
previous question中的细节).
type Atomic<T> = class type TFactory = reference to function: T; class function Initialize(var storage: T; factory: TFactory): T; end; 现在我想编写简化的初始化函数,它将从T中获取类型信息(只要typeof(T)为tkClass),并使用默认构造函数创建新实例(如有必要). 可悲的是,这失败了: class function Atomic<T>.Initialize(var storage: T): T; begin if not assigned(PPointer(@storage)^) then begin if PTypeInfo(TypeInfo(T))^.Kind <> tkClass then raise Exception.Create('Atomic<T>.Initialize: Unsupported type'); Result := Atomic<T>.Initialize(storage,function: T begin Result := TClass(T).Create; // <-- E2571 end); end; end; 编译器报告错误E2571类型参数’T’没有类或接口约束. 我如何欺骗编译器创建T类的实例? 解决方法
您可以使用新的Delphi Rtti来完成此任务.给定解决方案的缺点是,如果构造函数未命名为Create,则它将无法正常工作.如果你需要让它一直工作,只需枚举你的类型方法,检查它是否是一个构造函数,并有0个参数,然后调用它.在德尔福XE工作.示例代码:
class function TTest.CreateInstance<T>: T; var AValue: TValue; ctx: TRttiContext; rType: TRttiType; AMethCreate: TRttiMethod; instanceType: TRttiInstanceType; begin ctx := TRttiContext.Create; rType := ctx.GetType(TypeInfo(T)); AMethCreate := rType.GetMethod('Create'); if Assigned(AMethCreate) and rType.IsInstance then begin instanceType := rType.AsInstance; AValue := AMethCreate.Invoke(instanceType.MetaclassType,[]);// create parameters Result := AValue.AsType<T>; end; end; 更新解决方案: class function TTest.CreateInstance<T>: T; var AValue: TValue; ctx: TRttiContext; rType: TRttiType; AMethCreate: TRttiMethod; instanceType: TRttiInstanceType; begin ctx := TRttiContext.Create; rType := ctx.GetType(TypeInfo(T)); for AMethCreate in rType.GetMethods do begin if (AMethCreate.IsConstructor) and (Length(AMethCreate.GetParameters) = 0) then begin instanceType := rType.AsInstance; AValue := AMethCreate.Invoke(instanceType.MetaclassType,[]); Result := AValue.AsType<T>; Exit; end; end; end; 并称之为: var obj: TTestObj; begin obj := TTest.CreateType<TTestObj>; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |