internal/privateフィールドの命名法は宗教論争?
共通言語仕様 (Common Language Specification)の準拠が極力求められるpublic/protectedメンバーと違い、internal/privateメンバーは内部で閉じているので、CLSを意識する必要はない。
もっとも、C#、VB.NET、C++/CLIなど、複数の言語に対応したコードジェネレータは、各言語の仕様を意識した作りになっている。
- VB.NETは大文字・小文字を区別しないので、プロパティのストレージフィールドの実装にcamelCaseを使用できない
- C++では先頭のアンダースコア付きの認識子は予約語のために予約されているのでフィールドの実装に使用出来ない(使用するなとされている)
internal/privateフィールドの命名法(C#)は、
- camelCase (Windows Formなど)
- _camelCase (.NET Core/Auto propertyの実装)
- camelcase1_camelcase2_camelcase3... (Mono)
- camelCase + Field (WCF Service Proxy)
など、さまざま。
英語が得意じゃないのでなんとなく、読み解いた感じだと・・・
「コンストラクタやメンバーアサインメソッドの引数と被るのは良くない」 (アンダースコア肯定派)
「thisをいちいち付けるのはナンセンス」 (アンダースコア肯定派)
「先頭アンダースコアは、m/s/g/tと同じスコープ依存の表記でハンガリアンの悪しき慣習」 (アンダースコア否定派)
全体的には、thisはコードジェネレータのコードを除き、避ける傾向があるようだが、アンダースコアについては宗教論争の様相を呈している・・・
いろいろ調べてみた感じだと、個人的には
「先頭アンダースコアはJavaのコミュニティ文化が持ち込まれたもの」 (最初のオープンコミュニティの規約がJavaをベースに作成)
「マイクロソフトはコンパイラやデザインエディタがアンダースコアを積極的に使用してきた歴史的背景があるので、基本的にはなじまない」
という解釈。
後者の例を挙げると・・・
- Windows Formなどのデザインエディタのイベントハンドラはコントロール名とイベント名をアンダースコアで繋げたもの
- マネージCOMクラスのデフォルトインターフェースは、クラス名の先頭にアンダースコアをつけたもの
- Auto propertyに対応したフィールドは、プロパティ名のcamelCaseの先頭にアンダースコアをつけたもの
この辺は、C++のアンダースコアの使い方も元になっていると睨んでいる。
Windows Formだと、
「componentsフィールド/コントロール配置時のデフォルトフィールド名がcamelCaseな時点でアンダースコアはアウトだよね」
と思う。
そもそも
「MSDNのマネージコードのサンプルで先頭アンダースコアを見た記憶がない」
そういう意味では、.NET Coreの異質さは目立っているように見えてしまうのは気のせいか・・・
それはさておき、同じ名前の認識子があるとコンパイルエラーになるので、将来、糖衣構文の導入で内部予約の認識子とコンフリクトが発生するようなアンダースコアの使用は避けるのが無難と個人的には思っている。
逆を言うと、MVVMパターンのプロパティ実装のように、パターンが決まっていて糖衣構文になる可能性が高いというケースでは、アンダースコアを積極的に使っても良いかもしれない。
混在させると見栄えが悪いので、アセンブリのターゲット領域(GUI/WCF/DB...)や、使用しているフレームワークに合わせて変えるのも正解とも思う。
「いわゆる『郷に入れば郷に従え』って奴」
そういう意味では、組織全体やプロジェクト全体では固定しない方が良く、もう少し小さな単位で決めたら良いのではないか・・・
実際、職場では、Java系のコーディング規約を真似して、「internal/privateフィールドは_camelCase (デザインモードは例外)」とした結果
「Windows FormでデザインモードのcamelCaseと_camelCaseが混在」
「Windows Formでデザインモードも含めて_camelCaseにした結果、イベントハンドラがアンダースコアで始まっている」
という痛い結果になっていたので、最近規約から外してもらった。
絶対やっちゃだめなのが・・・
「個人の趣味に任せる」
最悪、プロジェクト内で宗教戦争になって、コミット合戦になりかねない。
「その辺はかっこの扱いの方が深刻」
あくまでも「個人的な見解」なので戦争はご遠慮ねがいます。