我可以通过声明声明类的类型:
type
TMyObject = class(TSomething);
TMyObjectClass = class of TMyObject;
我正在尝试做这样的事情:
IData<TIn,TOut> = interface;
IData = interface
function GetGenericData<Tin,TOut>: IData<TInput,TOut>;
function GetInType: TRttiType;
function GetOutType: TRttiType;
end;
声明一个可以访问泛型类型的基类型,并提供有关通用输入和输出类型的信息。
IData<TIn,TOut> = interface(IData)
['{5B402458-22EC-4A8B-83F3-C11AC575B79E}']
function GetInput(Index: Integer): TIn;
function GetInputCount: Integer;
function GetOutput(Index: Integer): TOut;
function GetOutputCount: Integer;
property Input[index: integer]: TIn read GetInput;
property Output[index: integer]: TOut read GetOutput;
property InputCount: integer read GetInputCount;
property OutputCount: integer read GetOutputCount;
end;
这是包含2个数据数组的实际泛型类型。请注意,输入和输出不需要是相同的类型。
然后我有一个包含一个或多个不同类型的IData
的类。
TStage = class(TPipelineStage, IData);
TStage<TIn, TOut> = class(TStage, IData<TIn, TOut>);
TMyPipeline = class
fStages = TArray<TStage>; <<-- this is really a list of TStage<?,?>
我想在班上列出不同的TStages,但很明显我无法对其进行编码
如何从TStage<IInterfaceA, InterfaceB>
访问TStage<InterfaceB, InterfaceB>
和fStages
?
我可以在此上下文中使用class of ....
并从那里实例化一个对象吗?
我使用这种方法的原因是我在如此声明的Pipeline阶段使用委托:
TDelegate<TIn, TOut> = reference to procedure(const Data: IData<TIn, TOut>);
答案 0 :(得分:3)
Delphi语言存在一些限制,会阻止您按照您尝试的方式执行操作。拿代码:
IData<TIn,TOut> = interface;
IData = interface
function GetGenericData<Tin,TOut>: IData<TInput,TOut>;
function GetInType: TRttiType;
function GetOutType: TRttiType;
end;
这里有一个接口中的泛型方法。 Delphi(至少在XE3之前)不支持接口中的泛型方法。
在其他snipet中你有:
TStage = class(TPipelineStage, IData);
TStage<TIn, TOut> = class(TStage, IData<TIn, TOut>);
TMyPipeline = class
fStages = TArray<TStage>; <<-- this is really a list of TStage<?,?>
代码中问题的答案是否。这是一个数组,而不是列表。但是,由于您的数组中包含TStage
的实例,因此无论TStage<TIn, TOut>
和TIn
是什么类型,它都会保留TOut
的实例,没有任何问题。
你有这个问题:
我想在我的班级中列出不同的TStages,但显然我无法对其进行编码。 如何从fStages访问TStage和TStage?
实际上,你可以!可以声明某个类型的列表(在您的情况下为TStage
)并保存降序类的实际实例,甚至是通用子类。
在我看来,您希望一个泛型方法将已经键入的TStage
实例返回到降序类型,以避免类型转换和某些类型测试,最终返回nil
如果stage是另一个类的实例,对吧?
在这种情况下,泛型方法可能会有所帮助,但仅限于类,而不是接口。我会做这样的事情(我手头没有Delphi来测试代码,但这个想法似乎符合你的需求):
interface
type
TMyPipeline = class
private
FStages: TObjectList<TStage>;
public
// Constructors, destructor and other methods...
function StageAs<TIn, TOut>(aIndex: Integer): TStage<TIn, TOut>;
end;
implementation
function TMyPipeline.StageAs<TIn, TOut>(aIndex: Integer): TStage<TIn, TOut>;
var
stage: TStage;
begin
stage := FStages[aIndex];
if stage.InheritsFrom(TStage<TIn, TOut>) then
Result := TStage<TIn, TOut>(stage)
else
Result := nil;
end;