【问题标题】:Why am I getting E2531 "Method requires explicit type argument"为什么我收到 E2531“方法需要显式类型参数”
【发布时间】:2018-12-01 07:34:24
【问题描述】:

下面的代码非常依赖泛型,我认为暴露了泛型处理中的一个错误。但也许有一些我不明白的地方。

编译器报错:

E2531 方法“CreateBaseItem”需要显式类型参数

上线:

foo3 := TFactory.CreateBaseItem<TDescendentFunctionsGroup2.Select>;

但据我所知,实例化 foo1foo4 应该基本相同。这个完整的程序突出了这个问题:

program SO53568763;

type
  TBaseItem = class(TInterfacedObject);

  IListableItem<T> = interface
    ['{6FD07ACB-04BB-4BFC-A38C-9B98F86DBC25}']
  end;

  TSomeDescendent = class(TBaseItem, IListableItem<TSomeDescendent>)
  end;

  TSelectFunctionsGenerator<T: TBaseItem, IListableItem<T>> = class(TBaseItem)
  end;

  TFunctionsGroup<T: TBaseItem, IListableItem<T>> = class
  public
    type
      Select = TSelectFunctionsGenerator<T>;
  end;

  TDescendentFunctionsGroup1 = class(TFunctionsGroup<TSomeDescendent>);
  TDescendentFunctionsGroup2 = TFunctionsGroup<TSomeDescendent>;

  TFactory = class
  public
    class function CreateBaseItem<T: TBaseItem>: T;
  end;

class function TFactory.CreateBaseItem<T>;
begin
end;

procedure Foo;
var
  foo: TSelectFunctionsGenerator<TSomeDescendent>;
  foo1: TFunctionsGroup<TSomeDescendent>.Select;
  foo2: TDescendentFunctionsGroup1.Select;
  foo3: TDescendentFunctionsGroup2.Select;
begin
  foo := TFactory.CreateBaseItem<TSelectFunctionsGenerator<TSomeDescendent>>;
  foo1 := TFactory.CreateBaseItem<TFunctionsGroup<TSomeDescendent>.Select>;
  foo2 := TFactory.CreateBaseItem<TDescendentFunctionsGroup1.Select>;
  foo3 := TFactory.CreateBaseItem<TDescendentFunctionsGroup2.Select>;
end;

begin
end.

奇怪的是TDescendentFunctionsGroup2.Select 足够显式地声明该类型的变量,但不够显式地用作CreateBaseItem 的泛型参数。

【问题讨论】:

  • 我想它来自单元/项目的其他部分。尝试编译您的代码 - 一切正常 - gist.github.com/lynxnake/e49072f7871314567fe97c005eeed999
  • @SerhiiKheilyk 上面的代码来自一个全新的 delphi 项目,我创建该项目是为了演示该问题。除了我上面发布的内容之外,其中没有任何内容。您使用的是哪个版本的 Delphi?
  • 东京,Delphi 10.2 更新 3,版本信息 - 25.0.31059.3231
  • 顺便说一句,我很确定您的代码上方至少应该有表单类声明和接口使用列表。否则编译错误将与这些部分丢失有关。我至少会给我发布的 sn-p 一些尝试
  • 请注意,我通过删除可视化组件简化了您的代码,并使其成为一个完整的程序。

标签: delphi generics delphi-10-seattle


【解决方案1】:

这似乎是一个编译器错误。 TDescendentFunctionsGroup1TDescendentFunctionsGroup2 的区别在于前者是从TFunctionsGroup&lt;TSomeDescendent&gt; 派生的新类,后者是TFunctionsGroup&lt;TSomeDescendent&gt; 的别名。

所以我的猜测是解析器或编译器在泛型类型的别名方面存在问题。

无论如何,我真的不确定别名给你带来什么好处,所以我只是这样写:

var
  foo3: TFunctionsGroup<TSomeDescendent>.Select;
...
foo3 := TFactory.CreateBaseItem<TFunctionsGroup<TSomeDescendent>.Select>;

【讨论】:

  • 这一切的重点在于,在 TFunctionsGroup 中,我创建了 20 个其他通用函数。所以我所要做的就是 TMyAlias=class(TFunctionsGroup.Select,而是 TMyTypeFuncs.Select。如果 TMyType 是一个长名称,它只是节省了一些输入。
猜你喜欢
  • 2014-11-22
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-23
相关资源
最近更新 更多