with文を使うべきもっともな理由もあるし、使うべきでないというもっともな理由もある。
要するにこの問題は宗教論争の範疇なので各自で双方の主張を理解して
自分なりのスタイルを一つ選択してそれを一貫して使い続けるのが重要である。
間違っても他人のスタイルにあれこれ文句を言ってはいけない。
withは使うべきではない。
with文は可読性を低下させバグをもたらすので使うべきではない。
以下の例はButtonのイベントハンドラをクリアするつもりでForm1のものをクリアしてしまっている。
// わりと無理やりな例 procedure TForm1.Button1Click(Sender: TObject); begin with Label1.FocusControl do // FocusControlにはButton1..4のどれかがぶら下がっている。 begin OnClick := nil; // イベントハンドラをクリア end; end;
// こっちはコンパイルエラーが出るのですぐバグだと分かる procedure TForm1.Button1Click(Sender: TObject); begin Label1.FocusControl.OnClick := nil; // イベントハンドラをクリア // ↑コンパイルエラーになる。↓に書き換えよう。 // (Label1.FocusControl as TButton).OnClick := nil; end;
(反論)
デバッガで追っていけば変数が適切に変更されないことがすぐに分かる。
withに関係するバグはこの一種類のみなので慣れればすぐに分かる。
with文を使わなくても別に困らない。
コピーペーストすれば問題ない。
begin foo.bar.baz.prop1 := 1; foo.bar.baz.prop2 := 'aaa'; foo.bar.baz.prop3 := Self; end;
あるいは参照を利用して以下のように書ける。
var shortcut: TFooBarBaz; begin shortcut := foo.bar.baz; shortcut.prop1 := 1; shortcut.prop2 := 'aaa'; shortcut.prop3 := Self; end;
(反論)
わざわざ変数を用意するのであれば、やせ我慢せずにwith文を使えばいい。
withは使うべきである。
with文は無駄な重複を省き可読性を向上させる。
これはwith文の主目的である。
with文を使うと速度が速くなる。
以下のようなコードはForm1->ListView?->Itemsと毎回参照をたどっていき、さらにItems[1]を取得するためのメソッドがコールされるので非効率的である。
Form1.ListView1.Items[1].SubItems.Add('foo'); Form1.ListView1.Items[1].SubItems.Add('bar'); Form1.ListView1.Items[1].SubItems.Add('baz');
with文を使うと, この作業が一度で済むので効率的である。
with Form1.ListView1.Items[1] do begin Add('foo'); Add('bar'); Add('baz'); end;
(反論)
参照を利用すれば同等のことが可能。
withの現実的な使い方
underconstruction 誰か書いて
|