文の構文はかなり主観的であり、好みについて議論することはできません。ただし、注目すべきは、ステートメントの両方の形式がC#のシンタックスシュガーであるということです。砂糖の慢性的な問題は、それが腐った歯を生み出すことです。この種の構文は、実際に何が起こっているのかを隠し、C#プログラマーを永遠に困らせます。
最初の短い形式では、コンパイラが実際に内部でデリゲートオブジェクトを作成することを完全にわかりにくくしています。オブジェクトを作成することは、ガベージコレクターが常に正しく行うことを信頼するのと同じくらい、フロアマットの下に隠したいことではありません。残念ながらそうではありません。これにより、関数のコールバックを必要とするpinvokeを使用するプログラマーが問題を抱えることになります。古典的なケースはSetWindowsHookEx()で、コールバックを使用して、フックされたイベントの通知をWindowsに配信させます。これは非常に一般的に次のように書かれています:
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);
ここで、 hookProcはコールバックメソッドです。それは機能しません、それは数秒後にプログラムをクラッシュさせることが保証されています。C#コンパイラは、hookProcを呼び出すことができるようにデリゲートオブジェクトを自動的に作成し、それをSetWindowsHookEx関数に渡します。問題は、そのオブジェクトへのライブ参照がどこにも存在しないことです。ガベージコレクターは、ネイティブコードがそのオブジェクトを使用していることを確認できません。したがって、次のガベージスイープはオブジェクトを破棄します。これは、後でWindowsがコールバックを行うときに大きな問題になります。少なくとも長い形式では、C#プログラマーがオブジェクト参照を別の場所に格納したほうがよいことに気付く可能性があります。
長い形も面倒で、長さが足りません。C#コンパイラが実際にこの参照を使用するデリゲートオブジェクトを作成することは完全にわかりにくくなっています。これは、デリゲートターゲットがインスタンスメソッドの場合に発生します。これは、C#プログラマーが次のようなコードを作成するとうまくいきません。
SystemEvents.UserPreferenceChanged +=
new UserPreferenceChangedEventHandler(repaintControls);
ここで、repaintControlsは、ユーザーがテーマを変更したときにすべてのコントロールを再描画するフォームのインスタンスメソッドです。ここで問題になるのは、デリゲートオブジェクトがこの値をキャプチャし、静的イベントに割り当てることです。イベントハンドラーの登録を再度解除するコードを明示的に記述しない限り、フォームオブジェクトは永久に参照されたままになります。この要件は明白ではありません。確かに砂糖からではなく、Winformsプログラミングでは非常にまれな要件です。ただし、これは非常に厄介なメモリリークのバグであり、プログラムが十分に長く実行されると、メモリ不足の例外でプログラムが簡単にフォールオーバーする可能性があります。
まあ、どちらの構文も完璧ではなく、C#言語では、デリゲートターゲットのオブジェクトを明示的に割り当てるC ++/CLIのような完全な構文は許可されていません。IDEチームは、岩と困難な場所のどちらかを選択する必要がありました。彼らは岩を選んだ。VS11は、間違いなく人気のある需要に触発されて、困難な場所になります。