1

just a short question regarding how to use TThreadList. Is it safe to use it with "with" statement as follows:

  with FEngineList.DAQEngines.LockList do
  begin
    try
      for Idx := 0 to Count - 1 do
        Items[idx].Param1 := cos(2*pi*I/Count);
      ...
      ...
    finally
      FEngineList.DAQEngines.UnlockList;
    end;
  end;

or should I explicitly do it like here:

  uEngines := FEngineList.DAQEngines.LockList;
  try
    with uEngines do
    begin
      for Idx := 0 to Count - 1 do
        Items[idx].Param1 := cos(2*pi*I/Count);
      ...
      ...
    end;
  finally
    FEngineList.DAQEngines.UnlockList;
  end;

Thanks!

Nix
  • 581
  • 5
  • 20
  • 4
    I've never seen a case where the conciseness of with is worth the scope pollution risk – David Heffernan May 15 '15 at 10:33
  • 2
    The 2 options are equally (un)safe... Code maintainability is not about writing minimalist "code-golf". It's about making the code as clear and unambiguous as possible. In this regard using **with** at all introduces an overlap in scope. This requires more programmer effort to assess exactly where each identifer inside the with block is scoped to. And therefore 'safety' in accurately interpreting and modifying the code is reduced. – Disillusioned May 15 '15 at 11:14
  • 1
    If you don't use with, you don't have the problem, right? Use your second example -- it's clearer and easier to read. – Nick Hodges May 16 '15 at 11:52

2 Answers2

2

It's upon you which variant you choose. with only tells the compiler where to get members you write in your code. So yes, it is safe, as long as you're accessing members you wanted to. It doesn't affect the runtime.

I would prefer the first way, just without that begin..end block (if I'd be forced to use with), but it's just my personal preference and you are free to write it as you wish:

with FEngineList.DAQEngines.LockList do
try
  ...
finally
  FEngineList.DAQEngines.UnlockList;
end;
TLama
  • 75,147
  • 17
  • 214
  • 392
2

Neither variant is to be recommended. If you had to choose between these two, the former is preferable since there is no real need for an extra local variable.

However, with is to be avoided. The problem is that is introduces potential for scope overlap. If the original scope and the object that is the subject of the with have members with the same name, then the with scope hides the outer scope. This catches you out when you add a new member to the subject of the with that happens to have the same name as a member of the outer scope. At best your program won't compile. At worst it compiles and you have a defect. Quite possibly a defect that you don't readily spot.

Code it like this:

uEngines := FEngineList.DAQEngines.LockList;
try
  for Idx := 0 to uEngines.Count - 1 do
    uEngines.[Idx].Param1 := Cos(2*pi*Idx/uEngines.Count);
    ....
  end;
finally
  FEngineList.DAQEngines.UnlockList;
end;

Related: Is Delphi "with" keyword a bad practice?

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I am familiar with "With" keyword "issues". However my case is quite simple and straightforward so this shouldn't be a problem. I always like to hear pros and cons from different programmers so I can create my objective opinion (as possible). Thanks! – Nix May 15 '15 at 13:44
  • 1
    It doesn't really matter how simple your case is, `with` doesn't give enough advantages to outweigh the risk. – David Heffernan May 15 '15 at 13:53
  • I see. According to my case I can easily get rid of "with" as well. – Nix May 15 '15 at 13:56
  • 1
    Clearly there is a matter of judgement here. I don't think that benefits of using `with` justify the risk. But you may judge otherwise. I just offer you my humble opinion. – David Heffernan May 15 '15 at 13:58