_var
クラスフィールドに変数名が表示されることはよくあります。下線はどういう意味ですか?これらすべての特別な命名規則のリファレンスはありますか?
_var
クラスフィールドに変数名が表示されることはよくあります。下線はどういう意味ですか?これらすべての特別な命名規則のリファレンスはありますか?
回答:
下線は単なる規則です。これ以上何もない。そのため、その使用法は常に各人によって多少異なります。問題の2つの言語でこれらを理解する方法を次に示します。
C ++では、アンダースコアは通常、プライベートメンバー変数を示します。
通常、C#では、パブリックプロパティの基になるプライベートメンバー変数を定義するときにのみ使用されます。他のプライベートメンバー変数にはアンダースコアはありません。ただし、この使用法は、自動プロパティの出現により主に道端に行きました。
前:
private string _name;
public string Name
{
get { return this._name; }
set { this._name = value; }
}
後:
public string Name { get; set; }
public string Name { get; private set; }
。この場合、を使用できます。確かに、完全に不変ではありませんが、存在します。
_var
予約されていません。
C ++では、変数名またはパラメーター名の前にUNDERSCORESを使用しないことがベストプラクティスです。
アンダースコアまたはダブルアンダースコアで始まる名前は、C ++の実装者向けに予約されています。下線付きの名前は、ライブラリが機能するために予約されています。
C ++コーディング標準を読んだ場合、最初のページに次のように表示されます。
「命名を過度に規制しないでください。ただし、一貫した命名規則を使用してください:必須事項は2つしかありません。(p2、C ++コーディング標準、Herb SutterおよびAndrei Alexandrescu)
より具体的には、ISOワーキングドラフトは実際のルールを述べています。
さらに、一部の識別子はC ++実装で使用するために予約されており、それ以外では使用されません。診断は必要ありません。(a)二重アンダースコア__を含む、またはアンダースコアで始まり、その後に大文字が続く各識別子は、あらゆる使用のために実装用に予約されています。(b)アンダースコアで始まる各識別子は、グローバル名前空間の名前として使用するために実装に予約されています。
上記の制限のいずれかに誤って移動した場合に備えて、シンボルをアンダースコアで開始しないことをお勧めします。
このようなアンダースコアの使用がソフトウェアの開発時に悲惨である理由を、あなたはそれで確かめることができます:
次のような単純なhelloWorld.cppプログラムをコンパイルしてみてください。
g++ -E helloWorld.cpp
あなたはバックグラウンドで起こるすべてを見るでしょう。これがスニペットです:
ios_base::iostate __err = ios_base::iostate(ios_base::goodbit);
try
{
__streambuf_type* __sb = this->rdbuf();
if (__sb)
{
if (__sb->pubsync() == -1)
__err |= ios_base::badbit;
else
__ret = 0;
}
二重下線で始まる名前の数がわかります!
また、仮想メンバー関数を見ると、* _ vptrは、クラスで1つ以上の仮想メンバー関数を使用すると自動的に作成される仮想テーブル用に生成されたポインターであることがわかります。しかし、それは別の話です...
アンダースコアを使用すると、競合の問題が発生する可能性があり、手遅れになるまで、その原因となっているアイデアがまったくなくなります。
実際、_var
規約はC#やC ++ではなくVBから来ています(m _、...は別のものです)。
これは、プロパティを宣言するときのVBの大文字と小文字の区別を克服するために来ました。
例えば、そのようなコードは、それが考慮されるためVBは不可能であるuser
とUser
同じ識別子として
Private user As String
Public Property User As String
Get
Return user
End Get
Set(ByVal Value As String)
user = value
End Set
End Property
したがって、これを克服するために、一部の人はこのようにするために '_'をプライベートフィールドに追加する規則を使用しました
Private _user As String
Public Property User As String
Get
Return _user
End Get
Set(ByVal Value As String)
_user = value
End Set
End Property
多くの規則は.Netに関するものであり、C#とVB.NETの規則の間の一定性を保つために、同じ規則を使用しています。
私が言っていることのリファレンスを見つけました:http : //10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices
先行アンダースコア付きのキャメルケース。VB.NETでは、常に「保護」または「プライベート」を示し、「Dim」は使用しないでください。"m_"の使用はお勧めできません。プロパティと大文字小文字のみが異なる変数名を使用することはお勧めできません。特に、保護された変数はコンプライアンスに違反しているため、VB.NETでプログラムすると、あなたの人生が苦痛になります。メンバーに、アクセサー/ミューテータープロパティとは異なる名前を付ける必要があります。ここにあるすべての項目の中で、先頭のアンダースコアは本当に唯一の物議を醸すものです。個人的には、プライベート変数をアンダースコアなしのラクダの場合よりも個人的に好むので、変数名を「this」で修飾する必要はありません。コンストラクタや他の場所で名前の衝突が発生する可能性がある場所のパラメータと区別するため。VB.NETでは大文字と小文字が区別されないため、アクセサープロパティは通常、アンダースコアを除いてプライベートメンバー変数と同じ名前になるため、これはさらに重要です。m_に関する限り、それはまさに美学に関するものです。変数名に穴があるように見えるので、私(および他の多くの人)はm_ uglyを見つけます。それはほとんど不快です。私はいつもVB6でこれを使用していましたが、それは変数に先行アンダースコアを付けることができないためでした。私はそれが消えるのを見ることが幸せでした。Microsoftは、m_(およびストレート_)をコードで両方実行した場合でも、それらに対して推奨しています。また、まっすぐな「m」を前に付けることもできます。もちろん、これらは主にC#でコーディングするため、プロパティとは大文字と小文字のみが異なるプライベートメンバーを持つことができます。VBの人々は別のことをしなければなりません。言語ごとの特殊なケースを考え出すよりも、それをサポートするすべての言語の主要なアンダースコアをお勧めします。クラスを完全にCLS準拠にしたい場合は、C#で保護されたメンバー変数のプレフィックスを省略できます。ただし、実際には、保護されている可能性のあるすべてのメンバー変数をプライベートにし、代わりに保護されたアクセサーとミューテーターを提供するため、これについて心配することはありません。理由:簡単に言うと、この規則は単純(1文字)で読みやすく(他の先頭の文字に気を取られない)、プロシージャレベルの変数やクラスレベルのプロパティとの名前の衝突を回避できます。クラスレベルのプロパティ。それをサポートするすべての言語について、主要なアンダースコアをお勧めします。クラスを完全にCLS準拠にしたい場合は、C#で保護されたメンバー変数のプレフィックスを省略できます。ただし、実際には、保護されている可能性のあるすべてのメンバー変数をプライベートにし、代わりに保護されたアクセサーとミューテーターを提供するため、これについて心配することはありません。理由:簡単に言うと、この規則は単純(1文字)で読みやすく(他の先頭の文字に気を取られない)、プロシージャレベルの変数やクラスレベルのプロパティとの名前の衝突を回避できます。クラスレベルのプロパティ。それをサポートするすべての言語について、主要なアンダースコアをお勧めします。クラスを完全にCLS準拠にしたい場合は、C#で保護されたメンバー変数のプレフィックスを省略できます。ただし、実際には、保護されている可能性のあるすべてのメンバー変数をプライベートに保ち、代わりに保護されたアクセサーとミューテーターを提供するため、これについて心配することはありません。理由:簡単に言うと、この規則は単純(1文字)で読みやすく(他の先頭の文字に気を取られない)、プロシージャレベルの変数やクラスレベルのプロパティとの名前の衝突を回避できます。クラスレベルのプロパティ。保護されている可能性のあるすべてのメンバー変数をプライベートに保ち、代わりに保護されたアクセサーとミューテーターを提供するので、これについて心配する必要はありません。理由:簡単に言うと、この規則は単純(1文字)で読みやすく(他の先頭の文字に気を取られない)、プロシージャレベルの変数やクラスレベルのプロパティとの名前の衝突を回避できます。クラスレベルのプロパティ。保護されている可能性のあるすべてのメンバー変数をプライベートに保ち、代わりに保護されたアクセサーとミューテーターを提供するので、これについて心配する必要はありません。理由:簡単に言うと、この規則は単純(1文字)で読みやすく(他の先頭の文字に気を取られない)、プロシージャレベルの変数やクラスレベルのプロパティとの名前の衝突を回避できます。クラスレベルのプロパティ。
最初のコメンター(R Samuel Klatchko)が言及:C ++識別子でアンダースコアを使用する場合のルールは何ですか?これは、C ++の下線に関する質問に答えます。アンダースコアはコンパイラの実装者用に予約されているため、通常、先頭のアンダースコアを使用することは想定されていません。あなたが見て_var
いるコードは、おそらくレガシーコードか、または主要なアンダースコアを避けなかった古い命名システムを使用して育った誰かによって書かれたコードのいずれかです。
他の回答が述べているように、これはクラスメンバー変数を識別するためにC ++で使用されていました。ただし、デコレータや構文に関する限り、特別な意味はありません。したがって、使用したい場合はコンパイルされます。
C#のディスカッションは他にお任せします。
独自のコーディングガイドラインを作成できます。チームの他のメンバーに明確なドキュメントを書いてください。
_fieldを使用すると、Intelilsenseは_と入力するだけですべてのクラス変数をフィルターできます。
通常はBrad Adamsのガイドラインに従いますが、アンダースコアは使用しないことをお勧めします。
MicrosoftのC#の命名基準では、変数とパラメーターはIEの 小文字のキャメルケース形式を使用する必要があるとしていますparamName
。フィールドが同じ形式に従うことをするための標準も呼び出しますが、多くのチームが分かりやすく改善するために、アンダースコアの接頭辞を求めるように、これは不明確なコードにつながることができますIEを: _fieldName
。
C#では、Microsoft フレームワーク設計ガイドラインは、パブリックメンバーにアンダースコア文字を使用しないことを推奨しています。以下のためのプライベートメンバー、アンダースコアは使用にOKです。実際、Jeffrey Richter(ガイドラインでよく引用されます)は、たとえばm_を使用し、プライベート静的メンバーには "s_"を使用します。
個人的には、_を使用してプライベートメンバーをマークしています。"m_"と "s_"はハンガリー語表記に近づいています。これは.NETでは不快なだけでなく、非常に冗長になる可能性があり、多くのメンバーを含むクラスではアルファベット順にクイックアイスキャンを実行するのが困難です(すべての変数がm_で始まる10個の変数を想像してください)。 。
私は、クラスのメンバー変数に_var命名を使用しています。私が行う主な理由は2つあります。
1)後でコードを読み取るときに、クラス変数とローカル関数変数を追跡するのに役立ちます。
2)クラス変数を探すときにIntellisense(または他のコード補完システム)で役立ちます。最初の文字を知っているだけで、使用可能な変数とメソッドのリストをフィルタリングできます。
CおよびC ++言語に関する限り、名前の下線(先頭、中間、末尾)に特別な意味はありません。それは単なる有効な変数名文字です。「規約」は、コーディングコミュニティ内のコーディング慣行に由来します。
上記のさまざまな例ですでに示したように、最初の_は、C ++のクラスのプライベートまたは保護されたメンバーを意味する場合があります。
ちょっとした雑学かもしれない歴史を少しだけお話ししましょう。UNIXでは、コアCライブラリ関数と、カーネル関数をユーザー空間に公開するカーネルバックエンドがある場合、_は、何もせずにカーネル関数を直接呼び出す関数スタブの前にスタックします。最も有名でおなじみのこの例は、BSDおよびSysVタイプのカーネルでのexit()と_exit()です。exit()は、カーネルの出口サービスを呼び出す前にユーザー空間の処理を実行しますが、_exitはカーネルの出口サービスにマップするだけです。
したがって、_は「ローカル」のものに使用され、この場合、ローカルはマシンローカルです。通常、_functions()は移植可能ではありませんでした。そのため、さまざまなプラットフォーム間で同じ動作を期待するべきではありません。
次に、_のような変数名
int _foo;
心理的には、_は最初にタイプしなければならないのは奇妙なことです。したがって、他のものとの衝突の可能性が低い変数名を作成する場合は、特に、プリプロセッサ置換を処理するときに、_の使用を検討してください。
私の基本的なアドバイスは、コーディングコミュニティの慣例に常に従うことです。これにより、より効果的にコラボレーションできるようになります。
コードをVB.NETからも拡張可能にする必要がある場合は、C#で使用する完全に正当な理由があります。(そうでなければ、私はしません。)
VB.NETは大文字と小文字を区別しないためfield
、このコードで保護されたメンバーにアクセスする簡単な方法はありません。
public class CSharpClass
{
protected int field;
public int Field { get { return field; } }
}
たとえば、これはフィールドではなくプロパティゲッターにアクセスします。
Public Class VBClass
Inherits CSharpClass
Function Test() As Integer
Return Field
End Function
End Class
一体、field
小文字で書くことさえできません-VS 2010はそれを修正し続けます。
VB.NETの派生クラスに簡単にアクセスできるようにするには、別の命名規則を考え出す必要があります。アンダースコアのプレフィックスは、おそらく最も煩わしくなく、最も「歴史的に受け入れられている」アンダースコアです。
古い質問、新しい答え(C#)。
C#でのアンダースコアのもう1つの使用法は、ASP NET CoreのDI(依存性注入)です。readonly
構築中に注入されたインターフェイスに割り当てられたクラスのプライベート変数は、アンダースコアで始まる必要があります。クラスのすべてのプライベートメンバーにアンダースコアを使用するかどうかは議論の余地があると思います(ただし、Microsoft自体がアンダースコアを使用します)が、これは確かです。
private readonly ILogger<MyDependency> _logger;
public MyDependency(ILogger<MyDependency> logger)
{
_logger = logger;
}
このような命名規則は、コード、特に自分のものではないコードを読むときに役立ちます。強力な命名規則は、特定のメンバーが定義されている場所、メンバーの種類などを示すのに役立ちます。ほとんどの開発チームは、単純な命名規則を採用し、メンバーフィールドの先頭にアンダースコア(_fieldName
)を付けます。過去には、C#に次の命名規則を使用しました(これは、.NETフレームワークコードのMicrosoftの規則に基づいており、Reflectorで確認できます)。
インスタンスフィールド: m_fieldName
静的フィールド: s_fieldName
Public / Protected / Internal Member: PascalCasedName()
Private Member: camelCasedName()
これは、なじみのないコードを非常にすばやく読み取るときに、メンバーの構造、使用、アクセシビリティ、および場所を理解するのに役立ちます。