web-dev-qa-db-ja.com

フィールドにプレフィックスを付けないのはなぜですか?

私はハンガリアン記法のファンではありませんでした。本当に低レベルのプログラミングをしているのでなければ、いつもかなり役に立たないことがわかりましたが、すべてのC++プロジェクトで、ある種のハンガリアン記法のポリシーが適用されました。これにより、フィールドの場合はm_、静的の場合はs_、グローバルの場合はg_など、いくつかの「非ハンガリアン」プレフィックスを使用します。

すぐに私はそれがC#でどれほど役に立たないかを理解し、徐々に私の古い習慣をすべて落とし始めました...しかし「m_」のこと。パラメータ、ローカル、およびフィールドを区別できると非常に便利であるため、プライベートフィールドでm_プレフィックスを使用しています。

MSDNのフィールドページの命名規則 はすべきではないと言っていますが、理由は述べていません(たとえば、Googleの規則は一般的に処方を合理化する傾向があります)。

私がすべきではない理由はありますか、それともスタイルの問題だけですか。後者の場合、プレフィックスは一般的に悪いスタイルと見なされますか?コードベースで作業している他の人からの否定的な反応を期待できますか?

49
Trap

メンバーフィールドのアンダーバープレフィックスが好きです。画面上部のウィザードバーのメソッドの前に、すべてのメンバーフィールドがアルファベット順に表示されるため、ほとんどの場合、これが気に入っています。

WizardBar

52
Matt Brunell

必要な場合:

  • プロジェクトのコーディングガイドラインで、

すべきでない場合:

  • プロジェクトのコーディングガイドラインに、すべきではないと書かれている場合

ガイドラインがまだない場合は、自分またはチームが望むものを自由に選択して、最も快適に感じることができます。個人的にC++をコーディングするとき、私はメンバーにm_を使用する傾向がありますが、それは役に立ちます。他の言語、特に真のクラスのない言語(Javascript、Luaなど)でコーディングする場合、私はしません。

要するに、私は「正しい」方法と「間違った」方法があるとは思いません。

38
MattJ

C#3.0で自動実装されたプロパティ機能により、この規則の必要性が少なくなります。書く代わりに

string m_name;
public string Name { get { return m_name; } }

または

string _Name;
public string Name { get { return _Name; } }

(または他の規則)、あなたは今書くことができます

public string Name { get; private set; }

明示的なバッキングストア変数が不要になったため、名前を付ける必要がなくなりました。したがって、この議論全体を回避します。

明らかに、検証を実行するなど、明示的なバッキングストアが本当に必要な場合、この引数は適用されません。

21
Ðаn

私はm_、s _、_だけ、接頭辞なしで実験しました。私はすべての静的変数とインスタンス変数に_だけを使用することに決めました。静的変数とインスタンス変数を区別することは重要ではないと思います。理論的には良いように聞こえますが、実際には問題は発生しません。

同僚がかつてすべてのプレフィックスを削除するという説得力のある議論をしましたが、1つのプロジェクトでそれを試しましたが、予想よりもうまく機能しました。私はそれを次のプロジェクトに持ち越し、Intellisenseに「干渉」することに腹を立てました。次のような場合

int foo;
public int Foo
{
  get { return foo; }
}

Fooと入力し始めると、インスタンス変数とプロパティの両方が提案されます。変数の前にアンダースコアを付けると、煩わしい二重の提案がなくなるため、_だけを使用するように切り替えました。

11
ScottS

一部の人がほのめかしているように、MSガイドラインは次のように述べています。

フィールド名にプレフィックスを使用しないでください。たとえば、静的フィールドと非静的フィールドを区別するためにg_またはs_を使用しないでください。

私はたまたまこれに同意します。プレフィックスを使用すると、コードが見苦しくなり、重要でない文字でスペースが無駄になります。そうは言っても、フィールドとプロパティの両方が同じ名前になるプロパティをバックアップするためにフィールドを使用するのが一般的です(プライベートフィールドはキャメルケースで、プロパティはパスカルケースです)。 VBでは、VBは大文字と小文字が区別されないため、これは機能しません。このシナリオでは、単一の_プレフィックスを使用することをお勧めします。それ以上でもそれ以下でもありません。見た目だけです。クリーナー、私見。

11
Chris

MSDN .NETライブラリガイドライン に従おうとしています。 命名ガイドライン セクションが含まれています。

明らかに、これらはプロジェクトガイドラインの二次的なものです。

10
Ben S

私はプロパティのバッキングフィールドをアンダースコアでマークすることを好みますが(すでに述べたように、.NET 3.0+は自動プロパティのおかげで必要性を減らします)、「m」ではありません。一つには、私がそれらを使用するようになると、InteliSenseリストの一番上にそれらを置きます。

私はMSDNのガイドラインをブラッシュアップする必要があることを認めます。最近は状況が急速に変化する可能性があります。

10
argibson

Resharperのようなツールでは、プレフィックスの理由は実際にはありません。また、短いメソッドを作成すると、変数がどこから来ているのかをすぐに知ることができるはずです。最後に、静的なものとそうでないものの違いを区別する必要はあまりないと思います。なぜなら、できないことをやろうとすると、リシャーパーが赤線を引くからです。 resharperがなくても、おそらくコンパイラーによって保存されます。

9
rball

あなたが述べているのと同じ理由で、私は常にメンバー変数の前にm _を付け、静的変数の前にs _を付けます。メンバー変数の前にアンダースコアを付ける人もいますが、これはいつも少し奇妙に見えます(ただし、これは個人的な好みです)。

私が一緒に仕事をしているほとんどの人は、m_/s_プレフィックスを使用しています。一貫している限り、何を使用するかはそれほど重要ではないと思います。

6
Sean

私はそれらを決して使用しません。それはずさんなコーディングを奨励します。 MSDNコーディングガイドライン、それがあります。

5
Inferis

_を使用する理由はいくつかあります(m_ではありません)。

(1)MSのネーミングガイドにもかかわらず、多くのBCLの人がそれを行っています。 (彼らの ブログ をチェックしてください。)それらの人はフレームワークを書いているので、彼らはコピーする価値のあるいくつかの良い習慣を持っています。 MSDNで最も役立つサンプルコードのいくつかは彼らによって書かれているため、アンダースコア規則を使用しています。これは事実上の業界標準です。

(2)単一のアンダースコアは、ソースを読み取るだけでメソッドとクラスレベルの変数を明確にするための目立つが目立たない方法です。新しい(または古い)コードを一目で理解するのに役立ちます。はい、マウスオーバーしてIDEでこれを確認できますが、強制されるべきではありません。テキストエディタで読んだり、あえて紙で読んだりすることをお勧めします。

(3)メソッドが短くなるため、プレフィックスは必要ないと言う人もいます。後で必要に応じて、フィールドを自動実装プロパティに変更できます。しかし、実際のメソッドは必要な長さであり、フィールドとプロパティの間には重要な違いがあります(シリアル化や初期化など)。

脚注:ここでの使用では、m_のメンバーの「m」は冗長ですが、これらの古い命名規則の多くで、型名は大文字で始まり、インスタンス名は小文字で始まるという考え方の1つであったため、小文字でした。これは.NETには当てはまらないため、二重に冗長になります。また、ハンガリアン記法は、古いCコンパイラ(整数またはポインタのキャストや算術など)で役立つ場合がありましたが、C++でも、クラスを処理するときにその有用性が低下していました。

4
Nick Westgate

私が慣れているのは、プライベートプロパティが小さなアンダースコーンf.ex "string_name"を取得したことです。公開されたものは「名前」を取得しました。また、メソッドの入力変数に小さな文字「void MyMethod(stringname)」が付けられました。

静的constを取得した場合、多くの場合、大きな文字で書かれます。 static const MYCONST = "hmpf"

3
ThorHalvor

C++とC#の重要な違いが1つあります。それは、ツールのサポートです。確立されたガイドライン(または一般的なバリエーション)に従うと、C++にはなかった深いレベルのツールサポートが得られます。標準に従うことで、ツールは、他の方法で実行できるよりも深いリファクタリング/名前変更操作を実行できます。 Resharperはこれを行います。したがって、確立された基準の1つに固執します。

3
krosenvold

コードを編集するためにviまたはEmacsに固執しない限り、私のIDEはメンバーの差分表示を処理するので、特別な規則を使用することはめったにありません。これは、インターフェイスにIまたはCのクラス。

誰かが、インターフェイスのIプレフィックスの.NETスタイルについて説明してください。 :)

3
Magnus

@John Kraftが言及しているように、「正しい」答えはありません。 MattJが最も近いです-あなたは常にあなたの会社のスタイルガイドラインに従うべきです。ローマにいるとき、そしてそのすべて。

私の個人的な意見としては、ここで求められているので、m_を完全に削除することに投票します。

最良のスタイルは、可視性に関係なく、すべてのメンバーがPascalCasedであり(つまり、privateメンバーでさえ)、すべての引数がcamelCasedであるスタイルだと思います。私はこのスタイルを壊しません。

プロパティのバッキングストアフィールドにプレフィックスを付けたいという要望は理解できます。結局のところ、フィールドとプロパティを区別する必要がありますよね?私は同意します、あなたはしなければなりません。ただし、ポストフィックスを使用してください。

m_MyProperty(または私がかつて見たり宣伝したりした_MyProperty)の代わりに、MyPropertyValueを使用してください。読みやすく、理解しやすく、さらに重要なことに、インテリセンスでの元のプロパティ名に近いです。

結局、それが私が接尾辞を好む理由です。インテリセンスを使用してMyPropertyValueにアクセスしたい場合は、(通常は)「My <down-arrow> <tab>」と入力します。それまでは、MyPropertyMyPropertyValueだけが十分に近いためです。リストにあります。インテリセンスを使用してm_MyPropertyにアクセスする場合は、「m_My <tab>」と入力する必要があります。

私の意見では、それはキーストローク経済についてです。

3
Randolpho

私はこれを決してしません、そしてその理由は私が私の方法を短く保つことを[しようとする]からです。画面にメソッド全体が表示されている場合は、パラメーターが表示され、ローカルが表示されているため、クラスが所有しているものと、パラメーターまたはローカルが何であるかがわかります。

私は通常、特定の表記法を使用してパラメータとローカルに名前を付けますが、常にではありません。一貫性がないとしても私は何もありません。私は自分のメソッドが短いという事実に依存しており、Xのみを実行する必要があるときに、X、Y、およびZを実行しないようにしています。

とにかく、それは私の2セントです。

3
itsmatt

公式ガイドラインに最も近いのは StyleCop です。これは、ソースファイルを自動的に分析し、推奨されるコーディングスタイルからの違反を検出でき、VisualStudioや自動ビルドなどから実行できるMicrosoftのツールです。 MSBuildとして。

私たちはプロジェクトでそれを使用しており、開発者間でコードスタイルとレイアウトの一貫性を高めるのに役立ちますが、かなりを取得するのに少し時間がかかることに注意してください慣れている!

あなたの質問に答えるために-それはハンガリアン記法もm_のような接頭辞も許可しません(実際、それはアンダースコアの使用をまったく許可しません)。

2
Greg Beech

C/C++でのこの表記の利点は、宣言を検索しなくても、シンボルのタイプを簡単に確認できることでした。これらのスタイルは、Intellisenseと「Goto Definition」が登場する前に登場しました。ヘッダーファイルの数を知っている人の宣言を探すために、ガチョウを追いかけなければならないことがよくありました。大規模なプロジェクトでは、これは重大な煩わしさになる可能性があり、Cソースコードを見ると十分にひどいものでしたが、アセンブリとソースコードの混合と生の呼び出しスタックを使用してフォレンジックを行う場合はさらにひどいものでした。

これらの現実に直面すると、m_や他のすべてのハンガリーのルールを使用することは、見慣れないコードを見るときにシンボルのタイプを調べるだけでどれだけの時間を節約できるかという理由で、メンテナンスのオーバーヘッドがあってもある程度意味があり始めます。もちろん、Intellisenseと「Goto Definition」があるので、その命名規則の主な時間節約の動機はもはやありません。これ以上それを行う意味はないと思います。私は通常、一貫性を保ち、ツールのサポートをもう少し増やすために、.NETライブラリのガイドラインに従うようにしています。

2
Eric Cosky

私はこれで炎上するだろうと確信していますが、そうです。

これはMicrosoftの.NETライブラリガイドラインと呼ばれていますが、実際には Brad Abramsの ビュー( ここにドキュメント )-正当な理由がある他のビューがあります。

人々は、特定のスタイルに正当な理由があるというよりも、多数派の見方をする傾向があります。

重要な点は、特定のスタイルが使用される理由と、それが別のスタイルよりも好まれる理由を評価することです。つまり、誰もがやるべきことだと言っているからという理由だけでなく、スタイルを選択する理由があるのです。

古いスタイルのハンガリー語を使用しない基本的な理由は、チームごとに異なり、習得が難しい略語を使用することでした。これは、略語を使用しないことで簡単に解決できます。

利用可能な開発ツールが変わると、スタイルは最も意味のあるものに変わるはずですが、各スタイルアイテムには確かな理由があります。

以下は私の理由と私のスタイルガイドラインです-私は常に私のスタイルを改善して、より信頼性が高く、保守しやすいコードを作成する方法を探しています。

可変命名規則

私たちは皆、変数の命名規則についての見解を持っています。保守が容易な高品質のコードを生成するのに役立つさまざまなスタイルがあります。変数に関する基本的な重要な情報をサポートするスタイルであれば、問題ありません。特定の命名規則の基準は、信頼性が高く、保守が容易なコードの作成に役立つことです。使用すべきでない基準は次のとおりです。Microsoft(Brad Abramsなど)はそのスタイルを使用しないと言っています-Microsoftは、ExpressionBlendのバグを見るだけで常に最も信頼できるコードを生成するとは限りません。コードを読むときは、変数名が変数に関する3つの重要な事実を即座に伝える必要があることが非常に重要です。スコープは、スコープに使用されるものを明確に理解するタイプです。マイクロソフトは、IntelliSenseに完全に依存することをお勧めします。 IntelliSenseは素晴らしいです。ただし、すべての変数にマウスを合わせて、そのスコープとタイプを確認するだけではありません。変数がスコープ内にないと仮定すると、重大なエラーが発生する可能性があります。たとえば、参照変数がパラメーターとして渡され、ローカルスコープで変更された場合、メソッドが戻った後も変更は残りますが、これは望ましくない場合があります。フィールドまたは静的変数がローカルスコープで変更されたが、それがローカル変数であると思われる場合、予期しない動作が発生する可能性があります。したがって、変数を(マウスオーバーではなく)見るだけで、そのスコープを即座に知ることができることが非常に重要です。

スコープを示すための次のスタイルが提案されています。ただし、変数のスコープを明確かつ一貫して示している限り、どのスタイルでも完全に問題ありません。メソッドに渡されるm_フィールド変数p_パラメーターs_静的変数ローカル変数タイプ:特定のタイプで動作していると思われる場合、重大なエラーが発生する可能性があります。それらは実際には異なるタイプで動作しています-繰り返しますが、タイプを決定するために変数をマウスオーバーすることはありません。タイプが何であるかを知っていると仮定し、それがエラーの作成方法です。

略語:略語は、開発者ごとに異なる意味を持つ可能性があるため、悪です。ある開発者は、先頭の小文字の「s」が文字列を意味すると考えるかもしれませんが、別の開発者はそれが符号付き整数を意味すると考えるかもしれません。略語は怠惰なコーディングの兆候です-少し余分な時間をかけてフルネームを入力し、コードを維持する必要がある開発者に明確にします。たとえば、「str」と「string」の違いはわずか3文字です。コードを保守しやすくするために、それほど手間はかかりません。

組み込みデータ型の一般的で明確な略語のみが受け入れられますが、チーム内で標準化する必要があります。

自己文書化コード:変数名に明確な説明を追加すると、別の開発者がコードを読んで理解するのが非常に簡単になります。名前をわかりやすくして、チームマネージャーが開発者でなくてもコードを読んで理解できるようにします。

変数名パーツの順序:推奨される順序はscope-type-descriptionです。理由:IntelliSenseはすべての類似したスコープをグループ化し、各スコープ内でIntelliSenseはすべての類似したタイプをグループ化するため、ルックアップが簡単になります。他の方法で変数を見つけてみてください。非常に簡単です。スコープを見て理解し、タイプを見て理解するそれはかなり一般的なスタイルであり、理解しやすいですそれはFxCopに合格します

例:次にいくつかの例を示します。m_stringCustomerNamep_stringCustomerDatabaseConnectionStringintNumberOfCustomerRecordsまたはiNumberOfCustomerRecordsまたはintegerNumberOfCustomerRecordsこれらの単純なルールにより、コードの信頼性と保守性が大幅に向上します。

制御構造の単一行ステートメントすべての制御構造(if、while、forなど)の単一行ステートメントは、特定のステートメントが制御構造に属していることに気付かずに新しいステートメントを追加するのが非常に簡単であるため、常に中括弧で囲む必要があります。コンパイル時エラーを生成せずにコードロジックを破ります。

メソッド例外ラッピングすべてのメソッドは、トラップし、回復、識別、検索、ログ記録、および作成する場所を提供する外部のtry-catchでラップする必要があります。投げるかどうかの決定。アプリケーションがクラッシュするのは予期しない例外です。すべてのメソッドをラップして未処理のすべての例外をトラップすることで、すべての例外の識別とログ記録を保証し、アプリケーションがクラッシュするのを防ぎます。もう少し手間がかかりますが、結果は努力する価値があります。

インデントインデントは大きな問題ではありません。ただし、4つのスペースを使用し、タブを使用しないことをお勧めします。コードが印刷される場合、最初のプリンタータブは通常デフォルトで8スペースになります。開発者が異なれば、使用するタブサイズも異なる傾向があります。 Microsoftのコードは通常4スペースインデントされているため、Microsoftコードを使用し、4スペース以外を使用する場合は、コードを再フォーマットする必要があります。 4つのスペースにより、簡単で一貫性があります。

2
David Roh

C++ Coding StandardsSutter、HerbandAlexandrescum Andrei、2004)。アイテム#0のタイトルは「小さなものに汗を流さないでください。(または:標準化しないものを知ってください。)」です。

彼らは、「独自の命名規則を決定できない場合は、...プライベートメンバー変数likeThis _...」(覚えておいてください)と言って、この特定の質問に少し触れます。先頭の下線の使用は、C++の非常に特定の規則に従います)。

ただし、そこに到達する前に、一定レベルの一貫性を強調します。「...重要なことは、ルールを設定するのではなく、ファイル内ですでに使用されているスタイルと一貫性を保つことです...」

2
Ðаn

私はもうそのスタイルを使いません。これは、変数がどのように使用されているかをすばやく確認できるように開発されました。新しい開発環境では、変数の上にマウスを置くことでその情報を確認できます。これらの新しいツールを使用すれば、その必要性はなくなります。

2
Jay

選択肢が与えられたときはいつでも、ハンガリーのいぼを使うことはありません。これは余分な入力であり、意味のある情報を伝えません。良いIDE(そして私はこの機能の存在に基づいて「良い」を定義します)は、静的メンバー、インスタンスメンバー、メンバー関数、タイプ、 IDEによって提供できる情報でコードを乱雑にする理由はありません。これは、バージョン管理システムがその処理を担当する必要があるため、コメントアウトされた古いコードでコードを乱雑にしないことの当然の結果です。

2
rmeador

最善の方法は、同僚と基準について合意し、それに固執することです。すべての人にとって最適な方法である必要はありません。実際に同意する方法よりも、1つの方法に同意する方が重要です。

コード標準に選択したのは、メンバー変数のプレフィックスとして_を使用することです。その理由の1つは、インテリセンスでローカル変数を簡単に見つけられるようにすることでした。

その基準に同意する前に、私は別の基準を使用しました。プレフィックスをまったく使用せず、メンバー変数を使用していることを示すためにコードにthis.memberVariableを記述しました。

C#3のプロパティの省略形を使用すると、明示的なメンバー変数をあまり使用しないことがわかります。

2
Guffa

特定のガイドラインに基づいてコーディングしていない場合は、実際のm_表記を引き続き使用し、プロジェクトのコーディングガイドラインにそのように記載されている場合は変更する必要があります。

0

機能的であること。

  • グローバル変数は使用しないでください。
  • 静的変数は使用しないでください。
  • メンバー変数は使用しないでください。

本当に必要な場合、ただし本当に必要な場合に限り、アプリケーション/環境にアクセスするために1つの変数のみを使用します。

0
Mark Stock