在Delphi 2006中使用'WITH'语句调试问题

时间:2008-11-23 09:13:35

标签: delphi

  

可能重复:
  What's wrong with Delphi's “with”

调试在BDS 2006中使用'WITH'语句的代码时遇到问题 调试器不会在类或记录中显示变量的值。 我做错了还是BDS 2006有错误?

type
  TNumber = class
      Num: Integer;
  end;

implementation

{$R *.dfm}

var
   MyNumber: TNumber;

procedure TForm2.FormCreate(Sender: TObject);
begin
   MyNumber := TNumber.Create;
   MyNumber.Num := 10;   /// MyNumber.Num Can be seen with debugger
   with  MyNumber do
   begin
     Num := Num +1 ;           /// Num is not seen by the  debugger
     MyNumber.Num := Num +1 ;  /// MyNumber.Num is seen but Num is not seen by the  debugger
   end;
end;

编辑:

当然可以使用变量的全名 但是如果你有一个多层次的复杂结构,事情会变得非常混乱

8 个答案:

答案 0 :(得分:17)

许多其中一种语言功能认为

With属于“仅仅因为你拥有它并不意味着你必须使用它”类别。有几个非常的情况下,我会给它一个房间 - 我发现一两个案例,当使用极其复杂的多级结构时,它使用是必不可少的,而编译器不这样做正如你所期望的那样没有它并且更容易包含,但是在编写Delphi的10年中,我认为这些可以用一只手的手指来计算。

在示例中倾向于使用相当多,因为代码看起来更清晰,但实际上在查看代码时确定变量是简单还是结构的一部分会对维护产生影响你没有写或没有用过一段时间容易超过这个。在我使用的每个版本的Delphi上调试器的已知问题都是关键。

答案 1 :(得分:8)

当鼠标悬停在变量上时,调试器无法在您要检查的源代码中显示的变量与相关的with-statement之间建立连接。 您必须检查debug-watch窗口中的值并在那里指定完整变量,例如MyNumber.Num。

答案 2 :(得分:6)

with语句的调试问题是已知的。这是我看到它们时删除它们的原因之一。在我看来,你不应该以可维护性为代价来提高编码速度。

我看到很多(并且学会讨厌)的常见构造是:

with TMyObject.Create do
  try
    Method1(blah, blah, blah);
    Method2(blah, blah, blah);
  finally 
    Free;
  end;

甚至可以在with语句中添加更多构造:

with A, B, C, D do
  // Aargh!

但是,如果可以替换,则有时会使用with语句的有效用法:

A.B.C.D.E.Method1;
A.B.C.D.E.Method2;
A.B.C.D.E.Method3;
A.B.C.D.E.Method4;
A.B.C.D.E.Method5;
A.B.C.D.E.Method6;

使用

with A.B.C.D.E do begin
  Method1;
  Method2;
  Method3;
  Method4;
  Method5;
  Method6;
end;

尽管使用A.B.C.D.E有点疑问,但它往往是“delphi方式”。 但现在有了班级助手,我们可以有一个完全有效的解决方案:

TAHelper = class helper for TA
public
  procedure Method1;
endl

procedure TAHelper.Method1;
begin
  // You can (should) add sanity checks here.
  B.C.D.E.Method1;
end;

所以现在你可以使用:

A.Method1;

在我看来哪个好多了。

答案 3 :(得分:6)

with 语句是句法NutraSweet:它的味道很像语法糖,但留下了不好的余味,结果实际上长期有害。最好不要使用它。

答案 4 :(得分:5)

我很少使用 With..do ,而且往往会这样做

var
  Sc : TE_Type;
begin
  Sc := A.B.C.D.E;
  sc.Method1;
  sc.Method2;
  sc.Method3;
  sc.Method4;
  sc.Method5;
  sc.Method6;
end;

当然,Sc的一个不错的名字也不会受到伤害。我认为它比 with..do 更清晰,调试器发现自己好多了。所以,我非常喜欢'快捷'变量。

答案 5 :(得分:4)

“随着”引入歧义并且可能导致比解决的问题更多的问题。考虑一下就不使用它。

Castalia有一个重构可以帮助删除它们。

答案 6 :(得分:2)

我完全相信可怕的“with”子句被包含在内,所以书籍编写者不必在他们的示例代码中拥有所有那些丑陋的TWinComponent字符串。在现实生活中,在代码片段和教科书之外,几乎没有充分理由使用“with”。

主要原因是它破坏了调试器。调试器在查找变量的值时评估整个子句是非常不切实际的,所以它不是一个bug,它在我所知道的所有delphi调试器中都不受支持。如果你像我一样,坚持从程序员那里维护成千上万行,基本上把所有东西都复制到教科书之外,它会使调试成为一个活生生的地狱。

最重要的是,请勿使用 - 请注意......永远!

答案 7 :(得分:-1)

使用根本不是一个糟糕的做法。唯一不好的是你不能轻易地调试这些行,但如果你仔细使用它就没有任何问题。对于青少年而言,这可能不是一个好习惯,但如果你知道在哪里使用它,那就好了。

让EMBA以任何方式改进它,以避免常见的咆哮。