Delphi 2009 Обработка с

Кто-нибудь знает, чем отличается обработка «with» в Delphi 2009?

Вчера я исправил проблему, просто деконструировав «with» на полные ссылки, например, «with Datamodule, Dataset, MainForm». Delphi 2006 и ранее применяли к набору данных «Закрыть». Delphi 2009 применил «Закрыть» к MainForm и вышел из приложения!


person user122603    schedule 15.07.2009    source источник
comment
+1 Вопрос составлен так, чтобы получить действительно отличные ответы!   -  person Argalatyr    schedule 16.07.2009


Ответы (5)


Ничего не изменилось. Ваше предыдущее наблюдение было неверным. Объекты, упомянутые в операторе with, считаются "справа налево", поэтому в вашем примере сначала будет выполняться поиск MainForm, затем Dataset, а затем Datamodule. Так было всегда. Это как если бы вы написали это:

with Datamodule do
  with Dataset do
    with MainForm do begin
      Close;
    end;

См. Документацию по Delphi 2006; должен быть раздел с именем Объявления и операторы, в котором вы найдете Структурированные операторы, включая раздел С операторами.

Сделайте себе одолжение и не используйте with. Это создает бесконечные проблемы как во время отладки, так и во время обслуживания, причем обслуживание может быть выполнено даже человеком, написавшим код всего за день до этого.

person Rob Kennedy    schedule 15.07.2009
comment
Хммм ... Я проверил версию модуля от 2/7/2006 против версии от 2/2/2009, и я действительно добавил MainForm. В конце концов, в D2006 все было по-другому. - person user122603; 16.07.2009
comment
Итак, что рекомендуется вместо этого? Если вы используете DBComponent.DataSource.DataSet, нужно ли вводить локальную переменную для хранения ссылки? - person Larry Lustig; 04.03.2010
comment
Да, @Larry. Например: var dset: TDataset; dset := DBComponent.DataSource.Dataset; dset.foo; dset.bar; - person Rob Kennedy; 05.03.2010
comment
Фу! Для меня большая перемена. Ну что ж. . . - person Larry Lustig; 05.03.2010

With это зло. Я не знаю, сколько раз мне нужно это повторять, но, видимо, мы еще не достигли цели.

With можно только «безопасно» использовать с объектами, которые никогда не изменятся. Если вы примените его к объектам, которые вы определяете в своем собственном проекте, все ставки отключены, и я осмелюсь предположить, что вам лучше просто использовать части «if Random (50)‹ 25 »для выполнения вашего кода, по крайней мере, это задокументировано для странного выполнения.

Проблема в том, что как только вы начинаете возиться с объектом, вводить новые методы или свойства или переименовывать старые, все существующие with-операторы, использующие эти методы, могут изменить смысл. И не в изменении "Предупреждение: вызов неоднозначного метода". Код просто сделает что-то другое, чем это было раньше. Не говоря вам об этом.

Например, предположим, что у вас есть это:

with connection, file do
begin
    Close;
end;

тогда чего вы ожидаете? Что ж, это естественно, чтобы закрыть файл, поэтому я ожидаю, что файл будет закрыт. Далее предположим, что эта файловая переменная содержит объект типа TSomeOddFile, который не определяет метод Close, а скорее метод CloseFile. Вышеупомянутый оператор With вместо этого закроет соединение.

Все хорошо, это задокументировано, никто не писал этот фрагмент кода, думая, что файл будет закрыт, в конце концов, метод называется CloseFile для этого объекта, это просто мое предположение, которое неверно, и я не работаю над проектом. Пока что.

А затем кто-то исправляет это, переименовывая CloseFile в Close. Приведенный выше код начнет незаметно закрывать файл вместо соединения. Без предупреждений, без ошибок, компилируется так же хорошо, как и до того, как вы изменили имя метода. Работает так же отлично ^ ч ^ ч ^ ч, нет, погоди, не пойдет.

Так что да, with укусит тебя в задницу.

person Lasse V. Karlsen    schedule 15.07.2009
comment
+1, иногда понять, насколько плохо с этим, можно только на собственном опыте. - person skamradt; 15.07.2009
comment
Что ж, обучение должно работать, если вам рассказывают об опыте, так что вам не нужно проходить через это самому. СО прожигал для меня столько часов, пока я не обнаружил, что это за дымящаяся куча .... это на самом деле. - person Lasse V. Karlsen; 15.07.2009

Использование with A,B,C,D - плохая практика, поскольку изменения в других модулях могут внезапно привести к тому, что ваш код перестанет работать должным образом. Дополнительную информацию см. здесь или здесь (найдите "with keyword").

person Vinay Sajip    schedule 15.07.2009

Компилятор обычно довольно надежен, поэтому я бы не стал предполагать ошибку или изменение, пока вы действительно не исключили все остальное. Некоторые вещи, которые я могу быстро придумать:

1) Посмотрите, используете ли вы перегруженные функции или операторы. Поскольку определение STRING (и нескольких других типов) изменилось, можно выбрать другой вариант, поскольку сигнатура фактически изменяется.

2) также может быть, что какой-то включенный модуль теперь определяет идентификатор, который уже используется, и имеет приоритет над идентификатором, представленным в другом модуле.

Если нет, начните изолировать код с минимального примера, используя как можно меньше единиц. Делайте это шаг за шагом, поскольку фокус в том, что было последним изменением, когда изменилось поведение.

Разместите это (или URL-адрес) здесь, всегда интересно посмотреть.

person Marco van de Voort    schedule 15.07.2009
comment
+1 за фактический ответ на вопрос вместо того, чтобы повторять, что оператор with использовать не следует. - person Wouter van Nifterick; 21.01.2011

With..do следует использовать с осторожностью. В противном случае это бесконечный источник головной боли .... Я согласен с Робом Кеннеди и другими.

Как Крейг Стунц (в другом сообщении о with..do) и Lasse V. Karlsen, как было сказано выше, with..do может создать много ловушек.

person Fabricio Araujo    schedule 15.07.2009