Question

Lately, I have been noticing that anytime I use Rectangle variable with With...do statement, it doesn't work at all for some reason.

For instance:

var bounds:=new Rectangle(0,0,0,0);

with bounds do
begin
  X:=1;
  Y:=2;
  Width:=33;
  Height:=44;
end;

bounds' values remain zeros not whats in the with statement. However if I do the following, it works great.

var bounds:=new Rectangle(0,0,0,0);

bounds.X:=1;
bounds.Y:=2;
bounds.Width:=33;
bounds.Height:=44;

Is there any reason why it would do that.

Was it helpful?

Solution

What Hans Passant is trying to imply is that the "with" statement creates a copy of bounds, works on it, then throws it away. I don't have enough information to verify that, but I feel that it's unlikely - Delphi's assignment operator works by reference, so implicit shallow copies don't actually happen that often.

However, "with" statements intentionally create a special kind of variable scoping hell. You could be grabbing a field inside bounds, or you could be grabbing a field from the containing method, or you could even be grabbing a field from a previous unclosed "with" statement. Automatic refactoring can't touch a with statement. Adding a field to the class the with statement operates on can break your method.

Consider

with myLongNamedComponent.anotherLongNamedChild.pedanticRectangle do
begin
    x:=1;
    y:=2;
    width:=33;
    height:=44;
end;

This is actually better written as

var bounds := new Rectangle(0,0,0,0);
bounds.x := 1;
bounds.y := 2;
bounds.width := 33;
bounds.height := 44;
myLongNamedComponent.anotherLongNamedChild.pedanticRectangle := bounds;

TL:DR; the "with" statement is no longer considered good coding practice.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top