为什么我收到E2531“方法需要显式类型参数”

时间:2018-12-01 07:34:25

标签: delphi generics delphi-10-seattle

下面的代码在很大程度上依赖于泛型,我认为在泛型处理中暴露了一个错误。但是也许有些事情我不理解。

编译器会引发错误:

E2531 Method 'CreateBaseItem' requires explicit type arguments

在线:

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的通用参数。

1 个答案:

答案 0 :(得分:3)

这似乎是编译器错误。 TDescendentFunctionsGroup1TDescendentFunctionsGroup2之间的区别在于,前者是从TFunctionsGroup<TSomeDescendent>派生的新类,而后者是TFunctionsGroup<TSomeDescendent>的别名。

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

在任何情况下,我真的不确定别名给您带来什么好处,所以我只想这样写:

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