[英]Delphi : How to create a generic type programatically?
如何在Delphi中动态构造泛型类型?
让我解释
如果我有一个接口IMyInterface<T>
,
我想动态分配通用T
参数并以某种方式获得对该类型的引用。
function GetInterfaced(aType : PTypeInfo) : TRttiType
begin
Result := ???
// I want to return TypeInfo(IMyInterface<aType>);
// or a RttiType that corresponds to TRttiContext.GetType(IMyInterface<aType>)
end;
如何动态构建此泛型类型?
一个限制,我不能使用
function GetInterfaced<T> : TRttiType
begin
Result := TrttiContext.Create.GetType(TypeInfo(IMyInterface<T>))
end;
编辑
我正在尝试使用Stefan的Spring4d容器创建一个类型来解析组件
例如 :
function ResolveLookup(aModelType : PTypeInfo) : TObject
var aLookupType : PTypeInfo
begin
aLookupType := SomehowGetTypeOf(ILookup<aModelType>);
Result := FContainer.Resolve(aLookupType).AsObject;
end;
我真正的用例是我定义了一组模型(
TAssociate = class(TModel)
TUser = class(TModel)
TMandate = class(TModel)
我还为他们定义了“查找”视图:
TAssociateLookup = class(TForm, ILookupView<TAssociate>);
我在容器中注册了它们
FContainer.RegisterType<TAssociateLookup, ILookupView<TAssociate>>);
然后我定义了一个服务
function TLookupService.GetLookupFor(aModelTypeInfo : PTypeInfo) : IInterface
begin
Result := FContainer.Resolve(SomeHowGetTypeOf(ILookupView<aModelTypeInfo>).AsInterface;
end
问题是我不能使用TLookupService.GetLookupFor<T>
,但我必须使用TLookupService.GetLookupFor(aTypeInfo : TTypeInfo)
这是因为接口不能具有通用成员。
如果我定义一个服务接口,我得到一个编译错误
ILookupService = interface
GetLookupFor<T> : ILookupView<T>; // compilation error
end;
所以我必须在这里移动泛型参数
ILookupService<T> = interface
GetLookup : ILookupView<T>;
end;
但这意味着我必须为我想要使用的每种类型的查找都有一个ILookupService实例:
MyForm = class(TForm)
fAssociateLookupService : ILookupService<TAssociate>;
fMandateLookupService : ILookupService<TMandate>;
fTaskLookupService : ILookupService<TTask>
end;
代替
MyForm = class(TForm)
fLookupService: ILookupService;
end;
这就是我想要定义这样的界面的原因
ILookupService = interface
GetLookupFor(aType : PTypeInfo) : IInterface;
end;
所以我可以使用
procedure TMyForm.DoIt
var
aLookup : ILookupView<TMandate>;
begin
aLookup := fLookupService.GetLookupFor(TypeInfo(TMandate)) as ILookupView<TMandate>;
end;
我不认为T可以是动态的,编译器需要知道T在编译时的类型。
编译器为每种使用的T类创建一个泛型类。 例如:
IMyInterface<TObjectType1>
IMyInterface<TObjectType2>
它不会在运行时创建它们,它们是在编译时创建的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.