繁体   English   中英

Delphi:如何以编程方式创建泛型类型?

[英]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.

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