【问题标题】:Is it possible to typecast a callback function in Delphi?是否可以在 Delphi 中对回调函数进行类型转换?
【发布时间】:2018-03-21 15:01:06
【问题描述】:

Delphi TList.Sort() 方法需要一个 function (Item1, Item2: Pointer): Integer; 类型的回调函数参数来比较列表项。

我想摆脱回调函数中的类型转换,并想定义一个这样的回调函数:

function MyTypeListSortCompare( Item1, Item2 : tMyType ) : integer;
begin
   result := WideCompareStr(Item1.Name, Item2.Name);
end;

...
MyList.Sort(tListSortCompare(MyTypeListSortCompare));
...

但不幸的是,这会触发“无效类型转换”编译器错误。

是否有可能在 Delphi(2006) 中正确地对函数指针进行类型转换?

【问题讨论】:

  • 没有。这是不可能的。传递给该回调的类型转换项(回调必须与其声明匹配)。
  • 当然不是。但是想要这样做是没有意义的。您编写了一次排序过程代码,并且永远不会自己调用它。为什么要通过添加函数的骇人听闻的类型转换来使其更难以阅读和维护?
  • 我以Sort回调为例,我的问题不限于排序。

标签: function delphi casting delphi-2006


【解决方案1】:

我通常会这样做:

function MyTypeListSortCompare( Item1, Item2 : Pointer ) : integer;
var
  LHS: TMyType absolute Item1;
  RHS: TMyType absolute Item2;
begin
  result := WideCompareStr(LHS.Name, RHS.Name);
end;

【讨论】:

  • 我必须问,LHSRHS 代表什么? LR 很清楚,但是 HS?只是好奇:) 顺便说一句。像WideCompareStr(TMyType(Item1).Name, TMyType(Item2).Name); 这样的简单类型转换在这里可以做同样的工作。
  • @Victoria 我猜左边和右边
  • @Victoria 但是功能有点重,是我左手的东西比右手的东西重,有点;)
  • @Tom、LHSRHS 来自数学,但最终命名还不错。我使用AB 甚至用于回调参数(而不是12 后缀)。
  • @TomBrunberg 左侧和右侧是正确的。我不喜欢单字符变量名,所以 L 和 R 不在了。 LHS 和 RHS 比 Left 和 Right 短:-)
【解决方案2】:

可以进行类型转换,但需要在函数名称前加上“@”:

var
   MyList : TList;
begin
   ...
   MyList.Sort(TListSortCompare(@MyTypeListSortCompare));
   ...
end;

正如 cmets 中所指出的,当类型检查指针关闭时不需要类型转换,因此在这种情况下这也有效:

MyList.Sort(@MyTypeListSortCompare);

【讨论】:

  • 不需要演员表。 MyList.Sort(@MyTypeListSortCompare); 效果很好
  • "实际上不需要类型转换" - 仅当 Type-checked pointers 为 OFF 时,否则需要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
  • 2018-05-30
  • 2011-03-17
  • 2013-05-30
相关资源
最近更新 更多