使用GetTypeKind时如何触发编译时错误

时间:2015-04-08 15:12:31

标签: delphi delphi-xe7 type-safety

在XE7中,我们有新的编译器内部函数GetTypeKind(尚未记录),它允许我们在编译时提取类型的味道。

如果使用了错误的类型,以下代码将生成运行时错误:

//make sure T is a procedure/function
procedure TDetours<T>.CheckTType;
{$IF CompilerVersion >= 28}
begin
  // XE7 and up:Resolve all tests at compiletime.
  if (Sizeof(T) <> Sizeof(Pointer)) or (GetTypeKind(T) <> tkProcedure) then begin
    raise DetourException.Create('T must be a procedure or function');
  end;
{$ELSE}
  //Code for pre-XE7 versions
{$ENDIF}
end;

如果未使用正确的类型,我希望编译器生成编译时错误
这允许在较早阶段捕获任何错误。 这可能吗?

我的思路如下:
   - 如果测试为假,则测试中的代码不会生成    - 如果测试为真,那么代码就会生成。

是否有一些代码可以放入测试中,在生成代码时会使编译器运行,但是不会使解析器停止工作?

1 个答案:

答案 0 :(得分:3)

  

在XE7中,我们有新的编译器内部函数GetTypeKind(尚未记录),它允许我们在编译时提取类型的味道。

为了使您能够执行此操作,您需要能够将GetTypeKind放入条件表达式中。这样你就可以编写这样的代码:

{$IF GetTypeKind(T) <> tkProcedure}
  {$Message Fatal 'Invalid type'}
{$ENDIF}

但是编译器不接受这个。编译器要求$IF条件中的表达式为常量表达式,GetTypeKind(T) <> tkProcedure不是。

  

如果未使用正确的类型,我希望编译器生成编译时错误。这允许在较早阶段捕获任何错误。这可能吗?

这是不可能的。您可用的唯一机制是通用约束。并且通用约束没有足够的粒度来指定所需的约束。

我认为你最好的办法是在类构造函数中加一个断言。它看起来像这样:

class constructor TDetours<T>.CreateClass;
begin
  Assert(Sizeof(T) = Sizeof(Pointer));
  Assert(GetTypeKind(T) = tkProcedure);
end;