匿名方法

时间:2018-04-20 22:33:42

标签: delphi anonymous-methods delphi-10.2-tokyo typeinfo

对于需要类型" 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,0,0,0,0,225,48,180,0,0,0,0)< / p>

匿名方法是否从TypeInfo中排除,或者对某些调整有用。

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

1 个答案:

答案 0 :(得分:3)

这没有什么不寻常之处。

匿名方法是作为编译器生成的接口实现的,该接口具有与匿名方法匹配相同签名的Invoke()方法。这就是TTypeKindtkInterfaceIntfParentIInterface的原因。

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

How are anonymous methods implemented under the hood?

IntfFlagsTIntfFlagsBaseSet枚举值为TIntfFlag

TIntfFlag = (ifHasGuid, ifDispInterface, ifDispatch);
  

ifHasGuid
  接口具有GUID(全局唯一标识符)。

     

ifDispInterface
  是一个调度接口。

     

ifDispatch
  可以派遣。

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

更新:我使用XE2进行了测试,果然,我看到IntfFlags设置为序号64(TIntfFlag(6),如您所见),而不是序号6,如预期。我看到的和您看到的内容之间的唯一区别是,我看到Guid完全为空(全为零)。