Почему с ... высказываниями и прямоугольником не работают вместе безупречно?

StackOverflow https://stackoverflow.com/questions/8331118

Вопрос

В последнее время я заметил, что в любое время я использую переменную прямоугольника с С ... делать Заявление, это вообще не работает по какой -то причине.

Например:

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

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

Значения Bounds остаются нулями, а не то, что в операторе с. Однако, если я сделаю следующее, это прекрасно работает.

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

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

Есть ли причина, почему это сделало бы это.

Это было полезно?

Решение

Ганс Пассант пытается подразумевать, что утверждение «с» создает копию границ, работает над ним, а затем отбрасывает его. У меня недостаточно информации, чтобы проверить это, но я чувствую, что это маловероятно - оператор назначения Delphi работает по ссылке, поэтому неявные мелкие копии на самом деле не случаются так часто.

Тем не менее, «с утверждениями» преднамеренно создают особый вид переменной области ада. Вы могли бы захватить поле внутри границ, или вы можете захватить поле с содержащегося метода, или вы даже можете захватить поле из предыдущего открытого «с помощью». Автоматический рефакторинг не может прикоснуться к заявлению. Добавление поля в класс, на котором работает оператор, может сломать ваш метод

Рассмотреть возможность

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

Это на самом деле лучше написано как

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; Заявление «с» больше не считается хорошей практикой кодирования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top