web-dev-qa-db-ja.com

静的クラスメンバーと非静的クラスメンバー

私は、一般的にcシャープとプログラミングが初めてです。簡単な質問があります-静的/非静的変数に関するベストプラクティスは何ですか?.

クラスyに属する変数private int xがあります。この変数にアクセスするには、yを参照する必要があります。ただし、xが静的である場合、yへの参照なしでこの変数にアクセスできます。

クラスy内のいくつかのメソッドがこの値を参照する状況では、どちらが最善の方法ですか?

これが理にかなっていて、私の質問があまりにも基本的ではないことを願っています!

どうもありがとう

22
Sherlock

静的変数は、クラスのインスタンスではなく、クラスに属していると考える必要があります。

クラスのすべてのインスタンスでこの変数を同一にする必要がある場合は、静的変数を使用します。

そうでない場合は、インスタンス変数を使用します。

一般に、パブリック静的変数はbad practiceです-これは共有グローバルリソースであり、変更する場合はアクセスを同期する必要があります。グローバル状態を持つことは、できるだけ避けたいものです。

47
Oded

ベストプラクティスは、パブリックスタティックを避けることです。 OOPでは、クラスはそのメンバーを隠すことを意図しています。 Staticは、実際にはinstanceのメンバーではなく、typeのメンバーです。

静的は、シングルトンパターンを実装する場合に便利です。しかし、再び、彼らはプライベートであり、パブリックプロパティを通じてアクセスできるようにする必要があります。

静的クラスと静的クラスメンバー(C#プログラミングガイド) を読む必要があります。

7
Aliostad

まあ、それらが異なる目的に役立つので、私は1つがより良いと断定的に言うことができません。

OOPに精通していますか? OOPでは、クラスから直接アクセスできる静的オブジェクトまたはクラスのメンバー。非静的メンバーは、それが属するインスタンスからのみアクセスできます。

C#はメソッドについても同様の原則に従います。静的メソッドはクラスから直接アクセスできますが、非静的メソッド(または、呼び出したいインスタンスメソッド)はインスタンスからアクセスする必要があります。インスタンスメソッドではインスタンス化を行う必要があるのはそのためです。静的メソッドではインスタンス化する必要はなく、さらに非実用的です(以下を参照)。

OOPでは、インスタンス変数では保存できない値に静的変数が使用されます。例:存在するクラスのインスタンスの数を数えたいと仮定した場合それを単一のインスタンスにどのように保存しますか?

メソッドは同様の原則を使用します。クラスのインスタンス内で実行するのが実用的でない手順に使用する必要があります。私は、(専門用語ではなく)幅広い手順にそれらを使用する傾向があります。つまり、オブジェクトをインスタンス化する必要のない手順を意味します。例、2つのパラメーターを追加します。 (この使用法は正しい場合とそうでない場合がありますが、そうだと思います)

ただし、オブジェクトの2つのプロパティを追加する場合、メソッドは静的にはできません。すぐにわかるように、静的メソッドはクラス内のインスタンスメソッドまたは変数にアクセスできないためです。もちろん、静的メソッドは、インスタンス自体の一部ではないため、通知されない限り、静的メソッドはクラスのどのインスタンスからこれらを取得するかを知らないため、理にかなっています

これ以上複雑にならないように、ここでやめます。あなたが何かを誤解した場合、私に知らせてください。

4
Arash Afshinfar

選択はアーキテクチャによって異なります。

StaticTypeの一部を構成し、他はそのタイプのinstanceの一部を構成します。同じタイプの異なるインスタンスの間で共有状態(たとえば)が必要な場合は、staticを使用します。すべてのインスタンスが他のインスタンスから独立した独自の値を持つようにする場合は、instanceフィールドを使用します。

どちらの場合でも、ところで、パブリックfieldsのように公開することは避けますが、プロパティを使用します。

3
Tigran

私は Oded 氏に完全に同意します:

クラスのすべてのインスタンスでこの変数を同一にする必要がある場合は、静的変数を使用します。

そうでない場合は、インスタンス変数を使用します。

はい、クラスメンバーにstaticを追加すると、基本的に、インスタンスなしで、インスタンスの外部でのみアクセスできます。そして、はい、それはグローバルリソース、あるいはあなたが望むならグローバル変数にさえなります。

しかし、少なくとも別の( 大きく編集された )良い点があると思います...

グローバル変数として静的メンバーを使用すると、 [〜#〜] oop [〜#〜]

つまり、いったん静的メンバーを設定すると、オブジェクトとして渡すことはできません。グローバル変数として静的を使用するほど、 単体テスト / mock ing classes

そのためのソリューションがあります、 Singletons 。しかし、 warnings なしでは絶対に来ないでください!

一方、sureで本当にグローバル変数が必要な場合は、Toolbox pattern。これは、Singletonパターンのあまり知られていない拡張機能です。それは実際にはあまり知られていない、あなたがそれをグーグルで検索すると、それらのキーワード(toolbox pattern)でそれを見つけることができません。

事前に計画してください。続きを読む。より良い決断を下せるように、すべてのオプションについて知ってください。本を手に入れましょう。オブジェクト指向プログラミングは、物事を今すぐ機能させるだけでなく、長期的に役立つ概念を適用することに関するものです。

1
cregox

一般に、静的またはインスタンスのいずれかの変数をパブリックにしたい場合は、プロパティでラップして、そのように公開する必要があります。これは確かにあなたが従うのが大好きになる原則です。

しかし、他のいくつかの答えにもかかわらず、私は静的を使用しないとは言えません。静的は、どんな場合でも避けるべき悪魔ではありません。あなたがしなければならないことは、あなたがプログラムをきれいで維持しやすい限り、静的を使用するかどうかを決定します。

簡単に言えば、長老の言語ではなく、静的はこのクラスのどのインスタンスにも属さないが、それらに影響を与えるものを表します。インスタンスを生成するクラスの静的プロパティの例としては、インスタンスが内部で実行される計算に参加するために、クラスのすべてのインスタンスに対してグローバルである必要がある要因などがあります。この場合、そして私の意見では、この要素をすべてのインスタンスに持つのではなく、静的として宣言する方が良いです。特に、次の計算に影響を与えるためにプログラムの存続期間中にこの要素が変化する場合。

0
Dummy01

あなたは自分自身に質問をする必要があります:なぜxが静的である必要があるのですか?

Xを静的にすると、xがクラスAのすべてのオブジェクトの一部であることを意味しますが、xが静的でない場合、xは1つのオブジェクトの一部にすぎません。

Geleralでは、静的フィールドの使用はバグ追跡に苦労しますが、場合によっては非常に役立ちます。

Singeltonの使用を検討することをお勧めします http://en.wikipedia.org/wiki/Singleton

0