型名と大文字と小文字が異なるだけのパラメーター名を使用しているのは、C#の悪い習慣と見なされていますか?


43

クラスのプロパティに一致するパラメーター名に関して、これに似た質問が表示されますが、C#の大文字と小文字を除いて、パラメータータイプ名と同じパラメーター名の使用に関しては何も見つかりません。それは私が見つけることができる違反ではないようですが、それは悪い習慣と見なされますか?たとえば、次の方法があります

public Range PadRange(Range range) {}

このメソッドは範囲を取り、パディングが適用された新しい範囲を返します。したがって、一般的なコンテキストを考えると、パラメーターのよりわかりやすい名前を考えることはできません。しかし、「心理的距離」についてのCode Completeを読んだときに拾ったヒントを思い出します。それは言います

心理的距離は、2つの項目を区別できる容易さとして定義できます...デバッグするとき、類似する変数名間および類似するルーチン名間の心理的距離が不十分であることに起因する問題に備えてください。コードを作成するときに、問題を回避できるように、大きな違いのある名前を選択してください。

私のメソッドシグネチャには多くの「範囲」が続いているため、この心理的な距離に関して問題があるように感じます。今、私は多くの開発者が次のことをしているのを見ます

public Range PadRange(Range myRange) {}

私は個人的にこの大会に強い嫌悪感を持っています。変数名に「my」プレフィックスを追加しても、追加のコンテキストは提供されません。

私はまた次を見る

public Range PadRange(Range rangeToPad) {}

「私の」プレフィックスよりもこれが好きですが、それでも全体的には気にしません。私には過度に冗長で、変数名としてぎこちなく読みます。私には、メソッド名のために範囲がパディングされることが理解されています。

このようにすべてをレイアウトしたら、私の最初は最初の署名を使用することです。私には、きれいです。不要なときにコンテキストを強制する必要はありません。しかし、私は自分自身または将来の開発者にこの慣習を傷つけていますか?ベストプラクティスに違反していますか?


35
もっと説明的なパラメーターを思い付かない場合は問題ありませんRange range
ロバートハーヴェイ

21
この状況では、IDEは「範囲」と「範囲」に異なる色を付けるため、1つがタイプで、もう1つが変数名であることは本当に簡単にわかります。

10
ええ、私はそれを思い出します。それは考慮事項として設計ガイドラインにあります。「プロパティにそのタイプと同じ名前を付けることを検討してください。」 docs.microsoft.com/en-us/dotnet/standard/design-guidelines/...
ジェイソン・タイラー

11
また、罰金:(Range r少なくともメソッド本体が短い場合)およびRange toPad
ベルギ

19
"my"プレフィックスは、コード例で行われるものと常に考えていました。これは、コンテキストに応じて名前を別の名前に変更する必要があることを読者に示すために使用されていました。実際に実際のコードで終わるようなものではありません。
カペックス

回答:


100

これを考えすぎないでください、Range range結構です。私はそのような種類の命名をC#で15年以上、おそらくC ++ではるかに長く使用しており、実際の欠点を経験したことはまったくありません。

もちろん、すべて同じタイプの同じスコープ内に異なるローカル変数がある場合、それらを適切に区別するための精神的な努力を払うのがおそらく役立つでしょう。


6
追加する別の例外は、インスタンスが特定のアクションを実行している場合です。たとえば、パラメーターが必要な理由について、さらに説明する余地が少しあります。Wack(Bozo bozoToBeWacked)さらにパラメーターがオプションであり、そのシナリオのオブジェクトが何を意味するか/何が影響するかを説明する場合。私の経験則では、パラメーターが何をするかをコードを見なくても明らかでない場合は、より良い名前やコメントが必要です。
マイク

17
Wack(Bozo bozoToBeWacked)メソッド自体によって十分に表現されている変数名の冗長性の例と見なされます(したがって、元の質問ごとに望ましくありません)。 Wack(Person bozo)ただし、bozoのみがハッキングされることが予想されることを意味するため、より意味的に価値があります。
ミラル

2
2番目の段落で言及した場合、パラメーターの名前をのような名前に変更することがよくありますinitialRange。それはまだ非常に一般的ですが、ほぼ同じレベルの嫌悪感はありませんmyRange
ジャックス

@Miral:などの場合により関連性が高くなりますPunch(Bozo punchingBozo, Bozo bozoToBePunched)。詳細な命名は、複数のもの(ほとんど同じ単語で意味的に記述されているもの)を区別する必要がある場合により関連します。OPの提案はRange rangeToPad、彼の1つのパラメーターメソッドの例では必要ありませんが、いくつかのRangeオブジェクトを取り込むメソッドには非常に必要な場合があり ます。
フラット

7
@Flater Punch(Bozo source, Bozo target)が仕事をする
Thomas Ayoub

17

私はこれを常にします、それは私に素晴らしい心を与えています。メンバーに割り当てる必要があるコンストラクターに渡される引数である場合、私のメンバーもrangeという名前になり、割り当ては次のようになります。

this.range = range;

通常、Rangeという名前のプロパティがあります。

それらはすべて同じものであり、コンテキストが異なるだけなので、単一の名前を維持することは理にかなっており、1つの名前のみを覚えておく必要があります。それは一つのことです、違いは純粋に技術的なものです。

「this」を使用して、完全に適格なメンバーを厳しくする必要があります。しかし、それがStyleCopの目的です。

StyleCopサイドノート

論争が保証されています!

「これ」の使用に反対する人々へ:私は_、m、m_を見たが、何もなかった。言語自体は、クラスメンバーを扱っていることを示す、完全に明確で明確な、普遍的に認識可能な方法を提供しています。一体なぜすでに完璧な名前を切り取る独自の方法を作りたいのでしょうか?

私がそれを考えることができる唯一の理由は、他の方法がなかったので、実際にそれを行うことが理にかなったとき、それがC時代からのレガシー習慣であるということです。

「もっとキャラクターだ!」マジ?「コンパイル時間が急上昇します!」マジ?「入力時に小指を持ち上げる必要があります!」。入力時間は、総開発時間に重要な意味を持ちます。

私はあなたが慣れているものとは異なるスタイルが何らかの反対を提起することを認識しています。しかし、これを一貫して使用することは議論が困難です。私にとっての仕組みは次のとおりです。新しいコードファイルをプッシュする前に、StyleCopを実行すると、「this」修飾子を欠いているメンバーが多数見つかります。「これ」を入れます。クリップボードで、メンバーによって実行され、挿入します。まったく努力しません。

StyleCopはこれ以上のことを行います(笑)。開発者が(コードの書式設定のみを考慮して)後継者の保守作業をいらいらさせることができる多くの方法があります。StyleCopはそれらのほとんどを防ぎます。それは非常に貴重です。

あなたがそれに慣れていない場合:それは通常、あなたが1週間または2週間不平を言うようにし、それからあなたはそれを愛するでしょう。


19
ただし、this」を使用して完全修飾メンバーを厳しくする必要があります。「-1」this必要な場合以外は使用しないでください。それ以外の場合はノイズです。_rangeフィールドに使用し、this拡張メソッドを除いて必要になることはありません。
デビッドアルノ

12
@DavidArnoに同意します。「これ」は純粋なノイズです。「Range」はプロパティ、「_ range」はフィールド、「range」はパラメーターです。

8
@David変数がクラスメンバである場合、それは必須であり、引数またはローカル変数ではなくクラスメンバを見ていることを示すために任意のプレフィックスを打ちます。
マーティンマート

6
私のIDEは、変数を自分自身に割り当てる2番目に火の玉を発射します。
-Koekje

21
@DavidArnoのノイズよりも「ノイズ」の方_が望ましい理由を説明しthis.ます。私は、一方が言語によって強制された意味を持っている(そして通常は構文の強調表示を持っている)と主張しますが、もう一方はそうではありません。
クリント

9

メソッド、パラメーター、変数の命名に関する私の自己指導は非常に簡単です。

  1. 渡されたり返されたりするタイプが名前に含まれている場合、それは間違っています。
  2. 物の名前ではなく、意図したもので名前を付けます。
  3. コードは、書かれている以上に読まれることを常に覚えておいてください。

したがって、私の意見では、最適なメソッドシグネチャは次のようになります。

Range Pad(Range toPad)

メソッド名を短縮するのは一目瞭然です。

パラメーター名toPadは、そのパラメーターが埋め込みによって変更される可能性が高いことを読者にすぐに伝え、その後返されます。対照的に、という名前の変数については仮定できませんrange

さらに、この方法の実際のボディに、他のRangeあなたが持っているかもしれないので、導入されている変数は、彼らの意図によって命名する(必要がある)だろうpaddedunpadded... toPadそれらの命名規則に準拠しますが、rangeちょうど突き出しとゲル化しません。


3
padded/ unpaddedローカルの不変変数に適しています。しかし、可変toPadパラメータがある場合、パディングが行われた後、名前toPadはそれ以上適合しません(結果がすぐに返されない限り)。私はRange rangeそのような場合に固執します。
カペックス

@Kapep私はそれをただと呼びますresult。これは、取得し変更返さ。後者は名前から明らかであり、前者は後に続きます。変更されていない引数を返すことは意味がありません。
maaartinus

署名から、Padメソッドはを返しますRange。それは、私にとって、私が渡したものがその場で変更されずに保存され、新しいパディングRangeが返されることを意味します。。
アーロンM.エシュバッハ

1
あなたのアドバイスをどう思うかわからない。Pad(toPad)私はちょっと間違っていると感じています。しかし、あなたは自分の視点を守ることの良いポイントを作ります。あなたは私から+0を受け取ります!:)
エリックドゥミニル

質問では、「パディングが適用された新しい範囲を返す」と述べています。私はあなたがシナリオだと思う何のために自分の名前付けに同意するが、実際の質問のために私はレンジCreateRangeWithPadding(レンジ源)のようなもののために行くだろう
リチャード・ウィリス

3

コード要素(型、変数、関数、あらゆるもの)の命名について、自分に問うべき重要な質問は

タイプミスをした場合、コンパイラはそれを見つけてくれますか?

最悪のタイプミスのバグは、コードがコンパイルおよび実行されますが、微妙な理由により、予想とは異なる動作をするものです。そして、それはタイプミスによるものなので、通常、コードを検査しているのを見るのは非常に困難です。タイプミスによりコードのコンパイルが停止すると、コンパイラーは問題の原因となっている行にフラグを立て、簡単に見つけて修正することができます。

型と変数の大文字と小文字のみが異なる状況では、これが常に当てはまります。(またはほぼ常に-十分な努力で、あなたはそれを動作させることができると確信していますが、あなたは本当に試してみる必要があります。)だから私はあなたがそこにいると思います。

心配する必要があるのは、現在のスコープにrangeandと呼ばれる2つの変数、メソッド、関数、またはプロパティがある場合Rangeです。その場合、コンパイラは、おそらくだろう、それを通過させる、そしてあなたは、実行時に予期しない動作を取得するつもりです。これは、「2つの変数」または「2つの関数」だけでなく、これらのタイプのコード要素のうちの2つであることに注意してください。警告が表示される場合がありますが、それ以上の保証はできません。あなたは二つのタイプが呼び出さ宣言していた場合にも、同様の問題を抱えているrangeRange

また、ハンガリーの表記スタイルにも同じことが当てはまります。ハンガリーの表記スタイルでは、名前の前に1つ以上の文字が付けられ、それが何であるかについて何かを言います。という変数とRangeそれへのポインタが呼び出されている場合、たとえばPRangeを誤って見落としがちPです。C#はこれをキャッチするはずですが、CとC ++はせいぜい警告のみを出します。またはもっと心配なのは、doubleバージョンが呼び出されDRange、それをfloatバージョンにダウンサンプルするとしますFRange。フロート(キーがキーボード上で隣接しているので、簡単です)事故ずつとなりますあなたのコードを使用した種類の仕事を、そのプロセスは、解像度アンダーフローが不足すると、それは奇妙で予測不可能な方法で倒れるでしょう。

8文字、16文字、または任意の任意の制限の命名制限があった時代はもうありません。変数名が長いとコーディングに時間がかかると不平を言う初心者を時々聞きました。これについて文句を言うのは初心者だけです。真面目なコーダーは、本当に時間がかかるのはあいまいなバグを見つけ出すことであることを知っています -そして、命名の悪い選択は、その特定の穴に自分自身を落とす古典的な方法です。


読者への注意-C#の場合、人々は本当にハンガリー語表記を避けるべきです。構文の強調表示が問題にならない、または制限されていた古い時代には便利でしたが、今日では本当に役に立ちません。
T.サー-モニカの復活

@ T.Sar昔も、情熱をもってそれを嫌っていました!あなたが言うように、より良いIDEはそれが目指していた問題を解決しましたが、それでも頻繁に現れます。たとえば、歴史的な理由でWindows APIと通信する必要がある場合は、引き続き表示されます。人々の好みのスタイルが本当に好きなら、私は人々の好みのスタイルを完全に打ちたくはありませんでしたが、大文字/小文字が名前を台無しにする唯一の方法ではないことを示すためのフックとしてそれを使いたいと思いました。
グラハム

あなたがハンガリー記法の使用を提案していないことは承知していますが、若い開発者はクールな名前の物には大きな弱点があることも承知しています。「私のコードはこの極秘の忍者コーディングスタイルで書かれています-ハンガリー語表記!」若い人にはたまらなくクールに聞こえるかもしれません。私はあまりにも多くの開発者は、クールな単語の誇大広告に餌食に見てきた...ハンガリアン記法は、痛みは、ソースコードXXの形式与えるです
T.サール-復活モニカ

@ T.Sar本当です。「過去を覚えていない人はそれを繰り返す運命にある」とすべて。:/
グラハム

1
元のハンガリー記法について、またはMicrosoftによってどのように誤解されたについて「Windowsチームのドキュメンテーションライターが誤ってSystems Hungarianとして知られるようになったものを発明した」、三角測量エピソードのLeo LaporteによるJoel Spolskyのインタビューについて) 277、2016-12-12、04分00秒-06分35秒)?
ピーターモーテンセン

1

追加したい逸話の1つですが、Range rangeこれは構文的には合法ですが、デバッグやリファクタリングがより困難になる可能性があります。Range型の変数がたくさんあるファイルで、「range」という名前の1つの変数を探していますか?この命名の選択の結果、後でさらに作業を行うことになります。

ただし、これは主にコンテキスト依存です。それが30行のファイルである場合、私のステートメントは実際には機能しません。


7
ほとんどの人は、Windows開発のために、タイプとパラメーターまたは変数を区別するツールを使用します。あなたが説明することは、Unixでの古き良きgrep時代を思い出させます。
フランクヒルマン

1
@FrankHileman驚くかもしれませんが、Unixはまだ生きており、grepはまだ使用中です(:D)。grepはデフォルトで大文字と小文字を区別するため、前述の問題は存在しません。ただし、ターミナル依存型のWindows嫌いの人でも、IDEが一般的な検索ではるかに優れているため、ソースコードにgrepを使用することはめったにありません。
maaartinus

プラットフォームがポイントではないことに同意すると思います。grepは素晴らしいツールですが、リファクタリングツールではありません。そして、リファクタリングツールは、私が使用したすべての開発プラットフォームに存在します。(OS X、Ubuntu、Windows)。
エリックウィルソン

@EricWilsonかつて、grepとsedはUNIXで唯一のリファクタリングツールでした。
フランクヒルマン

@FrankHilemanリファクタリングツールとして何かが使用されているからといって、それが1つであることを意味するわけではありません。私はメモ帳でリファクタリングできますが、それはテキストエディタ以上のものではありません。
エリックウィルソン

1

私はあなたがRange range1つの理由で今日を使用できると思う:構文強調表示。最近のIDEは通常、型名とパラメーター名を異なる色で強調表示します。また、タイプと変数には、簡単に混同しないように、かなりの「論理的距離」があります。

これが当てはまらない場合は、別の名前を検討するか、この構文強調表示を行うことができるプラグイン/拡張機能を有効にしようとします。


0

関数がジェネリックである場合、パラメーターがジェネリックになるため、ジェネリック名を使用する必要があります。

あなたが言っていることではありませんが、誤解を招くほど具体的なパラメーター名を持つ汎用関数を実行する関数を見てきました。好む

public String removeNonDigits(String phoneNumber)

これは多くの状況で多くの文字列に適用できるように、関数名は非常に一般的に聞こえます。しかし、パラメータ名は奇妙に具体的であるため、関数名が誤解を招くのか、それとも...

確かに、Range rangeと言う代わりに、Range rangeToPadと言うことができます。しかし、これはどのような情報を追加しますか?もちろん、それはパッドする範囲です。他に何でしょうか?

「my」または「m_」などの任意のプレフィックスを追加すると、読者にゼロの追加情報が伝えられます。コンパイラが変数名を型名と同じにすることを許可しない言語を使用した場合-大文字と小文字を区別する場合としない場合-コンパイルするために、接頭辞または接尾辞を付けることがあります。しかし、それはコンパイラを満足させるためだけです。たとえコンパイラーが区別できたとしても、これは人間の読者が区別しやすくすると主張することができます。しかし、すごい、Javaで「Customer customer = new Customer();」のようなステートメントを書きました。10億回、私はそれを混乱させることはありませんでした。(私はいつも少し冗長だと感じていましたが、VBでは「新しい顧客として薄暗い顧客」と言うことができ、クラス名を2回指定する必要はありません。)

私がジェネリック名に強く反対するのは、同じ関数に同じ型のインスタンスが2つ以上ある場合です。特にパラメーター。好む:

public Range pad(Range range1, Range range2)

range1とrange2の違いは何ですか?どうやって知るの?本当に2つの一般的で互換性のある値である場合は、次のようになります。

public boolean overlap(Range range1, Range range2)

範囲が重なる場合はtrueを返し、重ならない場合はfalseを返すと予想されるため、これらは汎用的で互換性があります。

しかし、それらが異なる場合、それらがどのように異なるのかを教えてください!最近、地理的な場所に関するデータを保持する「Place」クラスを持ち、「p」、「place」、「place2」、「myPlace」などの名前のこのタイプの変数を持つプログラムに取り組んでいました。名前は、どちらがどれかを判断するのに本当に役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.