gpt4 book ai didi

delphi - 泛型无法正确解析方法类型

转载 作者:行者123 更新时间:2023-12-03 14:38:50 25 4
gpt4 key购买 nike

考虑以下因素:

{$APPTYPE CONSOLE}

uses
Generics.Collections;

type
TObjProc = procedure of object;
TFoo = class
public procedure DoFoo;
public procedure DoBar;
end;

procedure TFoo.DoFoo;
begin
WriteLn('foo');
end;

procedure TFoo.DoBar;
begin
WriteLn('bar');
end;

var
ProcList : TList<TObjProc>;
Foo : TFoo;
aProc : TObjProc;
begin
Foo := TFoo.Create;
ProcList := TList<TObjProc>.Create;
ProcList.Add(Foo.DoFoo);
ProcList.Add(Foo.DoBar);
for aProc in ProcList do aProc;
ReadLn;
end.

这会产生预期的输出

foo
bar

现在假设我们要从列表中分配一个过程。列举作品,如上所述。这也有效:

aProc := ProcList.Items[0];
aProc;

但这会引发编译器错误:

aProc := ProcList.First;
// E2010 Incompatible types:
//'procedure, untyped pointer or untyped parameter' and 'TObjProc'

这是双奇数,因为

function TList<T>.First: T;
begin
Result := Items[0];
end;

所以...发生了什么事?

这也会影响较新版本的 Delphi 吗?如果有合理的预期认为这应该有效(我认为确实如此),我很想对此进行质量控制。

最佳答案

这不是编译器错误,这个问题也确实与您对泛型的使用无关。 FirstLast 都是函数,因此编译器无法判断您是要调用它们还是引用它们。明确并让编译器知道您打算通过提供括号来调用该函数。

aProc := ProcList.First();
aProc := ProcList.Last();

您再次因在调用过程和函数时允许省略括号的决定而陷入困境。这个设计决策虽然在做出时看起来很有吸引力,但现在看起来就不那么吸引人了,因为过程类型在现代编码风格中得到了如此广泛的使用。

当您编写ProcList.First时,编译器会面临歧义。您的意思是调用该函数,还是希望将该函数作为过程类型引用?在许多情况下,编译器无法解决歧义,但此处情况并非如此,表达式位于赋值运算符的右侧。面对这种歧义,编译器会假设您要引用该函数。

之所以采取这个选择,是因为其他选择会更糟糕。至少通过这种方式,您可以提供括号并明确表明您要调用的函数。如果编译器走另一条路,那么您将不得不寻找一种方法来告诉它您打算引用该函数。

最后,如果 FirstLast 作为属性实现,就不会有歧义。

关于delphi - 泛型无法正确解析方法类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26144675/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com