繁体   English   中英

我可以将通用变量的类型作为参数传递吗?

[英]Can I pass the type of a generic variable as a parameter?

我可以通过声明以下内容来声明类的类型:

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<?,?>

我想在班上列出不同的TStage,但是显然我不能编写代码。
如何访问TStage<IInterfaceA, InterfaceB>TStage<InterfaceB, InterfaceB>fStages

我可以在这种情况下使用class of ....并从那里实例化一个对象吗?

我使用这种方法的原因是,我在这样声明的Pipeline阶段中使用了一个委托:

TDelegate<TIn, TOut> = reference to procedure(const Data: IData<TIn, TOut>);

Delphi语言有一个局限性,它会阻止您按照尝试的方式进行操作。 拿代码:

IData<TIn,TOut> = interface;
IData = interface
  function GetGenericData<Tin,TOut>: IData<TInput,TOut>;
  function GetInType: TRttiType;
  function GetOutType: TRttiType;
end;

在这里,您在接口中有一个通用方法。 Delphi(至少在XE3之前) 不支持接口中的通用方法。

换句话说,您有:

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实例,所以无论TInTOut是什么类型,它也将TStage<TIn, TOut> TOut

您有以下问题:

我想在班上列出不同的TStage,但是显然我不能编写代码。 如何从fStages访问TStage和TStage?

实际上, 您可以 可以声明某种类型的列表(在您的情况下为TStage ),并保存降级类(甚至是通用子类)的实际实例。

在我看来,您想要一个通用方法将已经键入的TStage实例返回为降序类型,以避免类型转换和某些类型测试,如果该阶段是另一个类的实例,则最终返回nil ,对吗?

在这种情况下,泛型方法可能会有所帮助,但仅适用于类而不适用于接口。 我会做这样的事情(我手头没有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; 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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