我有以下代码(简化):
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
Unit1 in 'Unit1.pas';
var
f: TFoo<Integer>;
begin
f := TFoo<Integer>.Create;
f.Baz;
Readln;
end.
unit Unit1;
{$D-}
interface
type
TFoo = class
public
procedure Bar(const s: string);
end;
TFoo<T> = class(TFoo)
public
procedure Baz;
end;
implementation
uses
TypInfo;
{ TFoo }
procedure TFoo.Bar(const s: string);
begin
Writeln(s);
end;
{ TFoo<T> }
procedure TFoo<T>.Baz;
begin
Bar(PTypeInfo(TypeInfo(T)).Name);
end;
end.
现在当进入f.Baz
时,我总是以Unit1.TFoo<T>.Baz
结束,尽管我明确禁用了该单元的调试信息,但我无法进入TFoo.Bar
这是正确的。我认为这是因为内部的泛型实现方式(如模板)以及我的TFoo<Integer>
中定义了Project1
。当我添加以下单元时,我无法再进入Baz
:
unit Unit2;
{$D-}
interface
uses
Unit1;
type
TIntegerFoo = TFoo<Integer>;
implementation
end.
现在有没有办法完全删除泛型类型的调试信息,所以我可以在任何地方(调试信息打开的地方)专门化那个类型,但是避免单步执行泛型类型的方法?我想这一定是可能的,因为我无法启用任何Generics.Collections.TList<T>
方法而不启用“use debug .dcus”选项。
答案 0 :(得分:3)
经过一些实验后,似乎是否启用调试信息的确定由引用该类型的特定实例的第一个单元控制。
因此,如果编译器第一次遇到类型的实例化,则启用调试信息,然后将使用调试信息编译特定类型。另一方面,如果第一个实例化是在没有调试信息的单元中,那么就没有调试信息。
在您的示例中,TFoo<Integer>
的第一个(也是唯一的)实例化位于.dpr文件中,该文件启用了调试信息。因此,如果您将{$D-}
移动到.dpr文件中,并在{$D+}
中设置Unit1
,您会发现TFoo<Integer>.Baz
没有调试信息。
我谈到第一个实例化的原因是可能有许多不同的单元实例化TFoo<Integer>
。编译器遇到的第一个是确定是否使用调试信息编译实例化类型的那个。
可以安排TFoo<Integer>
有调试信息,但TFoo<string>
没有调试信息。
我想这一定是可能的,因为我无法在不启用“use debug .dcus”选项的情况下执行任何Generics.Collections.TList方法的信息。
我无法解释。根据我的假设,如果第一次实例化类时调试信息已打开,则调试信息应该可用于TList实例化。
我怀疑调试器中可能存在错误。例如,我写了以下程序:
{$APPTYPE CONSOLE}
uses
Generics.Collections;
begin
TList<Integer>.Create.Add(6);
end.
当我关闭启用调试DCU运行时,我确实可以进入Generics.Collections
。但我走进了错误的地方。它落在TList<T>.Pack
。
所以,对不起,我无法提供更多的见解,但你问题的这一方面令我感到困惑。