私は、C# 2.0 で記述された大規模な (50 万行以上) WinForms アプリを開発および保守しています。このアプリはマルチユーザーで、現在約 15 台のマシンに展開されています。システムの開発は継続中 (永続的なベータ版と考えることができます) であり、毎週のビルドで導入される可能性のある新しいバグからユーザーを保護するための対策はほとんど講じられていません。
このような理由から、私はデバッガーの編集と継続に大きく依存するようになりました。これはバグの発見と修正だけでなく、場合によっては進行中の開発にも役立ちます。実行中のアプリケーションのコンテキスト内から新しく記述したコードを実行できることは非常に価値があると思います。再コンパイルして新しいコードに特定のエントリ ポイントを追加する必要はなく (ダミーのメニュー オプションやボタンなどをアプリに追加し、次の本番ビルドの前にそれらを削除することを覚えておく必要があります)、プロセスを停止することなくすべてをリアルタイムで試してテストできます。
私はエディット・アンド・コンティニューを非常に重視しており、それに完全に互換性のあるコードを積極的に書いています。たとえば、次のようなことは避けています。
- 匿名メソッドとインラインデリゲート(書き換えが完全に不可能な場合を除く)
- ジェネリックメソッド(安定した変更されないユーティリティコードを除く)
- 「任意の CPU」をターゲットとするプロジェクト (つまり、64 ビットで実行されない)
- 宣言時点でフィールドを初期化する(初期化はコンストラクタに移動されます)
yield
(ユーティリティコードを除く)を使用する列挙子ブロックの記述
現在、C# 3 および 4 の新しい言語機能は、エディット アンド コンティニュ (ラムダ式、LINQ など) とほとんど互換性がないことは十分承知しています。これが、プロジェクトをフレームワークの新しいバージョンに移行することに抵抗している理由の 1 つです。
私の質問は、これらのより高度な構造の使用を避けて、デバッグが非常に簡単なコードを使用することは良い習慣であるかどうかです。この種の開発には正当性がありますか、それとも無駄ですか? また、重要な点として、これらの構造 (ラムダ式、匿名メソッドなど) のいずれかが、適切に記述された編集継続互換のコードでは回避できるパフォーマンス/メモリのオーバーヘッドを引き起こすでしょうか? ...または、C# コンパイラの内部動作により、このような高度な構造は手動で記述された「拡張」コードよりも高速に実行されるのでしょうか?
ベストアンサー1
陳腐な言い方ですが、編集継続に頼るのではなく、単体テストや統合テストを書くのが良い習慣です。
そうすれば、一度労力を費やせば、他の時間は「無料」になります...
ここで私が提案しているのは、すべてのコードに対して遡及的にユニットを記述することではありません。むしろ、バグを修正する必要があるたびに、修正を証明するテスト (またはより一般的には複数のテスト) を記述することから始めます。
@Dave Swerskyがコメントで述べているように、Mchael Feathersの本は、レガシーコードを効果的に扱うは良いリソースです (書いた 5 分後にはレガシーになりますよね?)
ですから、編集と継続を可能にするために新しい C# 構造を避けるのは間違いだと思います。しかし、新しい構造をただ単に受け入れることも間違いだと思います。特に、新しい構造によってコードが理解しにくくなる場合は間違いだと思います。