加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 匿名方法对TypeInfo的奇怪行为

发布时间:2020-12-15 04:11:43 所属栏目:大数据 来源:网络整理
导读:对于需要泛型类型“family”的一段代码,我尝试使用TypeInfo来检索所需的信息. class function GetTypeKindT:TTypeKind; 对于大多数类型,我可以解决这个问题.但匿名方法类型表现出意外. 我有一个匿名方法类型定义为: TMethodProc = reference to procedure;
对于需要泛型类型“family”的一段代码,我尝试使用TypeInfo来检索所需的信息.
class function GetTypeKind<T>:TTypeKind;

对于大多数类型,我可以解决这个问题.但匿名方法类型表现出意外.

我有一个匿名方法类型定义为:

TMethodProc = reference to procedure;

我试着获取类型信息:

MyKind := GetTypeKind<TMethodProc>;

class function GetTypeKind<T>:TTypeKind;
var 
  TI: PTypeInfo;
begin
  TI := TypeInfo(T);

  ...
end;

我知道匿名方法背后有一些编译魔术.但我得到以下结果:

TI.TypeData.IntfParent == IInterface
TI.TypeData.IntfFlags == [(out of bounds)6]

标志有一个意外的值,TIntfFlag有三个值,所以6是意外的. GUID也不是指导.它有一个相同的8个字节的重复集,大多数是00.例如(0,225,48,180,0)

匿名方法是从TypeInfo中排除还是对某些调整有用.

另外,(奇怪的)6是一个无证的特征,还是可以是任何值?

解决方法

这没什么不寻常的.

匿名方法是作为编译器生成的接口实现的,该接口具有与匿名方法匹配相同签名的Invoke()方法.这就是为什么TTypeKind是tkInterface而IntfParent是IInterface.

接口后面是编译器生成的实现类,它包含捕获的变量,以及Invoke()实现中的匿名方法的主体.

How are anonymous methods implemented under the hood?

IntfFlags是TIntfFlagsBase,这是TIntfFlag个枚举值的Set

TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch);

ifHasGuid
Interface has a GUID (Globally Unique Identifier).

ifDispInterface
Is a dispatch interface.

ifDispatch
Can be dispatched.

Set是值的位掩码.每个枚举值由掩码中的特定位表示.在TIntfFlagsBase中,ifHasGuid为bit 0,ifDispInterface为bit 1,ifDispatch为bit 2.因此,数字值6(110b)将是ifDispInterface和ifDispatch标志启用,但不是ifHasGuid标志.因此,IntfGuid没有任何有意义的值,但仍占用TTypeData中的空间以进行对齐.

更新:我测试了XE2,果然,我看到IntfFlags设置为序数64(TIntfFlag(6),如你所见)而不是序号6,如预期的那样.我看到的和你看到的唯一区别是我看到Guid是完全空的(全为零).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读