具有记录类型的类型信息在运行时不起作用
Typeinfo with record type does not work at runtime
我在Delphi下编译有点问题:
function T_QS2ProcessMailbox.PutRec<T>(const aID: T_Barcode; var aRec: T;const aTxt: String): Boolean;
var
FA: T_FahrauftragRec absolute aRec;
LP: T_LagerpackungRec absolute aRec;
begin
init_Rec;
Rec.ID := aID;
Rec.EventTime := Now;
Rec.Text := aTxt;
if TypeInfo(T_LagerpackungRec) = TypeInfo(T) then
begin
Rec.RecType := C_QS_TYPE_TLAGERPACKUNGREC;
Rec.FA := FA;
end
else
if Typeinfo(T) = Typeinfo(T_LagerpackungRec) then
begin
Rec.RecType := C_QS_TYPE_TFAHRAUFTRAGREC;
Rec.LP := LP;
end
else
Rec.RecType := C_QS_TYPE_TEXT;
Send_TraceMsg(ClassName + '.PutRec Type=' + IntToStr(Rec.RecType));
Result := PutRec(Rec);
end;
它编译良好,没有错误、消息或提示。但它是在没有 if
语句的情况下编译的。您可以在图片中查看 - 此代码没有编译标记
我不明白为什么。
有人可以向我解释一下我做错了什么吗?
那些 if
语句可以在编译时解析,因此对于 T
的任何给定值,实际上只会编译其中的一个。 (换句话说,编译后的代码永远不会为这个函数执行任何if
)。
我可以想象只看到 1 个编译标记的 2 个原因。您的应用程序将只使用 1 个 if
语句,或者 IDE 会将所有 if
语句的编译标记映射到同一行(我发现最后一个不太可能,但我在 IDE).
中看到了一些奇怪的东西
另一种可能性是您的第二个 if
应该是
if Typeinfo(T) = Typeinfo(T_FahrauftragRec) then
而不是
if Typeinfo(T) = Typeinfo(T_LagerpackungRec) then
Typeinfo()
是 XE7 及更高版本中的 编译器内部函数 ,因此可供编译器在编译时计算 1。由于 T
的类型是编译器也知道的通用类型,因此编译器可以直接评估您的 if
和任何评估为 False
的块,并且永远不会在运行时从最终的可执行文件中完全省略。这就是为什么您在它们上看不到任何调试器点的原因。
1:但仅限于在通用方法内的 if TypeInfo(T) = TypeInfo(X)
语句中使用 TypeInfo(T)
的特定情况。 TypeInfo()
的其他用途在编译时没有类似地内联。
这是正常行为,也是您希望发生的事情,因为它会生成更精简、更高效的运行时代码。
当您的其他代码调用 PutRec<T_FahrauftragRec>(...)
时,T
将是 T_FahrauftragRec
,因此 TypeInfo(T_LagerpackungRec) = TypeInfo(T_FahrauftragRec)
将计算为 False。
同样,当调用 PutRec<T_LagerpackungRec>(...)
时,T
将是 T_LagerpackungRec
,因此 TypeInfo(T_FahrauftragRec) = TypeInfo(T_LagerpackungRec)
将计算为 False。
对于您传递给 T
的任何其他类型,依此类推。
此外,您的代码中存在错误。您的第二个 if
声明:
if Typeinfo(T) = Typeinfo(T_LagerpackungRec) then
应该是这样的:
if Typeinfo(T) = Typeinfo(T_FahrauftragRec) then
我在Delphi下编译有点问题:
function T_QS2ProcessMailbox.PutRec<T>(const aID: T_Barcode; var aRec: T;const aTxt: String): Boolean;
var
FA: T_FahrauftragRec absolute aRec;
LP: T_LagerpackungRec absolute aRec;
begin
init_Rec;
Rec.ID := aID;
Rec.EventTime := Now;
Rec.Text := aTxt;
if TypeInfo(T_LagerpackungRec) = TypeInfo(T) then
begin
Rec.RecType := C_QS_TYPE_TLAGERPACKUNGREC;
Rec.FA := FA;
end
else
if Typeinfo(T) = Typeinfo(T_LagerpackungRec) then
begin
Rec.RecType := C_QS_TYPE_TFAHRAUFTRAGREC;
Rec.LP := LP;
end
else
Rec.RecType := C_QS_TYPE_TEXT;
Send_TraceMsg(ClassName + '.PutRec Type=' + IntToStr(Rec.RecType));
Result := PutRec(Rec);
end;
它编译良好,没有错误、消息或提示。但它是在没有 if
语句的情况下编译的。您可以在图片中查看 - 此代码没有编译标记
我不明白为什么。
有人可以向我解释一下我做错了什么吗?
那些 if
语句可以在编译时解析,因此对于 T
的任何给定值,实际上只会编译其中的一个。 (换句话说,编译后的代码永远不会为这个函数执行任何if
)。
我可以想象只看到 1 个编译标记的 2 个原因。您的应用程序将只使用 1 个 if
语句,或者 IDE 会将所有 if
语句的编译标记映射到同一行(我发现最后一个不太可能,但我在 IDE).
另一种可能性是您的第二个 if
应该是
if Typeinfo(T) = Typeinfo(T_FahrauftragRec) then
而不是
if Typeinfo(T) = Typeinfo(T_LagerpackungRec) then
Typeinfo()
是 XE7 及更高版本中的 编译器内部函数 ,因此可供编译器在编译时计算 1。由于 T
的类型是编译器也知道的通用类型,因此编译器可以直接评估您的 if
和任何评估为 False
的块,并且永远不会在运行时从最终的可执行文件中完全省略。这就是为什么您在它们上看不到任何调试器点的原因。
1:但仅限于在通用方法内的 if TypeInfo(T) = TypeInfo(X)
语句中使用 TypeInfo(T)
的特定情况。 TypeInfo()
的其他用途在编译时没有类似地内联。
这是正常行为,也是您希望发生的事情,因为它会生成更精简、更高效的运行时代码。
当您的其他代码调用 PutRec<T_FahrauftragRec>(...)
时,T
将是 T_FahrauftragRec
,因此 TypeInfo(T_LagerpackungRec) = TypeInfo(T_FahrauftragRec)
将计算为 False。
同样,当调用 PutRec<T_LagerpackungRec>(...)
时,T
将是 T_LagerpackungRec
,因此 TypeInfo(T_FahrauftragRec) = TypeInfo(T_LagerpackungRec)
将计算为 False。
对于您传递给 T
的任何其他类型,依此类推。
此外,您的代码中存在错误。您的第二个 if
声明:
if Typeinfo(T) = Typeinfo(T_LagerpackungRec) then
应该是这样的:
if Typeinfo(T) = Typeinfo(T_FahrauftragRec) then