C#のフィールドとメソッドでプライベートを使用する必要がありますか?


8

私はC#に少し慣れており、次のことがわかりました。C#では、クラス内のすべてのフィールドとメソッドはデフォルトでプライベートです。これが意味すること:

class MyClass
{

string myString

}

と同じです:

class MyClass
{

private string myString

}

それで、それらは同じなので、フィールドとメソッドでprivateキーワードを使用する必要がありますか?多くのオンラインコードサンプルでは、​​コードでprivateキーワードを使用していますが、それはなぜですか?


34
まず、スコープ指定子を含めることを忘れるのではなく、フィールドをプライベートにするつもりだったことは明らかです。
KChaloux 2014

4
使用しないのが不快ですprivate。識別子宣言の最初の部分としてスコープ指定子を常に見ることが期待できる場合、それは私にとって認知的不協和を少なくします。最初の単語がスコープ指定子ではないことを理解するよりも、 "プライベート"を読む方が私の心の時間が少なくて済みます。つまり、それはプライベートメンバーの宣言であることを意味します。コードを書くことは、後でそれを読む必要があるということでもあります。
Robert Harvey

3
@RobertHarveyそれはまた完全に主観的かもしれません。C ++でコーディングするときは、オプションであるすべてのものを常に省略しました。自分のコードを読んでいる他の人がより詳細なコーディング規則に慣れているかもしれないことに気づくまで、気が散るのを感じたからです。したがって、それは好み(個人的なプロジェクトの場合)と慣習(共同作業の場合)の問題です。
marczellm 2014

2
@gnatこれがその質問の重複であるかどうかはわかりません。正しいリンクを投稿しましたか?
maple_shaft

4
@gnatコードでプライベートキーワードを明示的に宣言するのはなぜコーディングスタイルに関する問題なのかを尋ねるのは簡単です。この質問はそれよりもはるかに具体的です。標準的な答えは別の質問をカバーするかもしれませんが、より具体的な質問は時々独自の答えに値するかもしれないと思います。
maple_shaft

回答:


38

改行とインデントを省略しても、C#コンパイラが伝えたいことを理解できるからといって、自動的に行うのは良いことではありません。

using System; namespace HelloWorld{class 
Hello{static void Main(){Console.WriteLine
("Hello World!");}}}

人間の読者には、次の場合よりもはるかに読みにくくなります。

using System;
namespace HelloWorld
{
    class Hello 
    {
        static void Main() 
        {
            Console.WriteLine("Hello World!");
        }
    }
}

そして、それがここでの要点です。プログラムは2人の対象者向けに書かれています。

  • コンパイラーまたはインタープリター。
  • あなた自身と他のプログラマー。

後者は、書かれたものの意味を理解し、すばやく理解する必要がある人です。このため、長年にわたって浮かび上がってきたいくつかの優れた慣行があり、多かれ少なかれ一般的に受け入れられている準標準です。それらの1つは明示的なスコープキーワードを置くことであり、別の例は、次のように構文的に必要とされない場合でも、複雑な式の周りに余分な括弧を置くことです。

(2 + 5) & 4

2
+1特に最後の点について。厳密に言えば、プログラマは自分の言語の操作の順序を知っている必要がありますが、私は常に可能な限り余分な括弧を追加しようとします。以前は、どの操作が最初に来るのか、式が私が思うように。ときどき答えは「いいえ、間違えました」であり、ブラケットが適切に使用されている場合、特に5 + 5 * 5is などのケースを検討する場合3050一見すると予想されないように、これらの状況を回避できます。
Pharap 2014

1
+1。明示的な可視性修飾子が表示されない場合、少し頭がおかしくなります。一瞬、「デフォルトはパブリックかプライベートか」を考えなければなりません。私は常に修飾子を使用するからであり、誰かが使用しないときは、それは私を捨てます。
Greg Bair 2014

6
つまり**private** static void Main()?:)
Jesse C. Slicer 2014

6

.NETのプログラミング言語はC#だけではありません。他の言語では、さまざまなコンテキストで異なるデフォルトのアクセシビリティを使用できます。指定privateすると、コードを読む人にはそのようなアクセシビリティが意図されていることが明確になりますが、仕様を省略すると、メンバーがアセンブリ内で使用できるようになっていたかどうかなどの疑問が残ります(VB.NETのデフォルトのように)。 。異なるルールで複数の言語を使用する場合、明示的であることは特に役立ちます。

かどうかに関してprivate、またはprotected他の賛成で特に魅力的な引数が存在しない状態で支持されるべきで、決定はそれは、派生クラスは、その便利な何かをするためにメンバーを暴露することを可能にすることがより可能性があるかどうかに基づくべきですそれ以外の場合は不可能であるか、またはクラスの将来のバージョンが内部データ構造をより効率的な方法で変更するのを妨げます。で両方の状況の例を見ることができますList<T>

場合によっては、集計(Point構造など)のリストがある場合、アイテムをインプレースで更新すると便利な場合があります。場合はList<T>、派生クラスにそのバッキングストアを暴露、人は簡単に定義することができEditableList<T>方法で:

delegate void ActByRef<T1,T2>(ref T1 p1, ref T2 p2);

void ActOnItem<TParam>(int index, ref TParam param, ActByRef<TParam> proc)
{
  .. test index, then...
  proc(ref _arr[index], ref proc);
}

次に、次のようなものを使用して呼び出すことができます。

int adjustmentAmount = ...;
myList.ActOnItem(index, ref adjustmentAmount, 
  (ref Point pt, ref int dx) => pt.X += dx );

このような方法では、比較的大きな構造タイプでも効率的な更新が可能になります(コピーが不要なため)。List<T>内部を公開しないという事実は、そのような演算子を効率的に実装できるクラスを派生させることを不可能にします。

反対に、私が知っている限り、Microsoftはまだこの機能を利用していませんが、バッキングストアをプライベートにすると、の将来のバージョンでList<T>、ほとんどのデータを使用するときに、バッキングストアを85K未満の断片に分割できるようになります。タイプ、またはを使用する場合は1000アイテム未満doubleList<T>バッキングストアを派生クラスに公開している場合、このような分割は不可能です。


フィールドがプライベート既定されているように私はのC#コンパイラの共通中間言語の出力を期待していないint myFieldprivate int myField異なるように。そのため、私が他の.NET言語の解釈に開放されたままにしないでください。
ロイT.

@RoyT .:複数の言語が使用されている場合、アクセス指定子が省略されたメンバーが別の言語のデフォルトであるアクセス権を持つことを意図されていたことが明確ではない可能性があるというのが私の指摘でした。
スーパーキャット2014

ああ、わかりました。あなたは他の.NET言語を明示的に参照していたので、私はそれを人々ではなくプログラムを理解していないものとして理解しました。
ロイT.

1
@RoyT .:最初の段落を編集しました。それはそれをより明確にしますか?
スーパーキャット2014

2

はい、それを使用する必要がありますprivate:)キーワードが使用されているのは、それが一般的に受け入れられている慣行であり、クラスメンバーの意図されたスコープに関するすべての疑いを取り除くためです。

特にチームで作業する場合、読みやすさはコードで非常に重要です。コードの読みやすさをさらに詳しく知りたい場合、私がお勧めできる優れたリファレンスブックは、The Elements of C#Styleです。


-4

質問:

「C#のフィールドとメソッドでプライベートを使用する必要がありますか?」

素早い回答:

はい。ただし、コードロジックによって異なります。

長い退屈な拡張回答:

メンバーの可視性を常に指定することをお勧めします。

メンバーをデフォルトで「プライベート」として宣言するのは良い方法だと思います。

現実の世界では、代わりに「保護された」を使用します。

遅かれ早かれ、その非表示のメンバーは、サブクラスによって使用される可能性があります。

時には、良い質問は、反対の質問をすることで、よりよく答えられることがあります。

あなたの質問とは反対の質問は次のようなものです:

「C#のフィールドとメソッドで常にパブリックアクセス修飾子を使用する必要があります」

他のプログラミング言語では、設計に応じて、保護されたパブリックを「昇格」できます。

いくつかのメンバー(プロパティ、メソッド)が必要な(視覚的な)コントロールの深い階層ライブラリをたくさん使用しています。

公開する方が良い場合もあれば、しない場合もあります。


5
go-to指定子としてprotectedを使用することは悪い場合があります。サブクラスは、スーパークラスに設定されたエラーチェックや制限を回避できる可能性があるため、適切ではない可能性がある操作に対してスーパークラスを開く可能性があります。そうでない場合でも、余分なスコープ内変数でサブクラスを汚染します(たとえば、アクセサー付きの保護された変数は、サブクラスでそれを変更する2つの方法を提供します)。

2
-1:質問への対応を試みません。
mattnz 2014

1
公的および保護されたものは、私的で保護されたものよりも私見が近い それらはクラスのインターフェースの一部です。プライベートメンバーはブラックボックスの内部状態のみです。
Petter Nordlander 2014

+1は必要ない場合でもプライベートを宣言するのが好きだからです。優れたコードは、機能性と同様に、可読性を重視しています。
PhillyNJ 2014

2
-1デフォルトでprotectedを使用するのは恐ろしいアドバイスです。メンバーの可視性を後からいつでも増やすことができますが、コードを壊すことなく(ユーザーがコードを使用している場合)逆はできません。
Oliver Weiler 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.