プロパティvsメソッド


135

簡単な質問:いつ(C#で)プロパティを使用することにし、いつメソッドを使用することにしますか?

私たちはこの議論に忙しく、プロパティとメソッドのどちらを使用すべきかについて議論の余地がある領域を発見しました。一例はこれです:

public void SetLabel(string text)
{
    Label.Text = text;
}

例では、 LabelははASPXページ上のコントロールです。これをメソッドにするかプロパティにするか(この場合)の決定を管理できる原則はありますか?

最も一般的で包括的な答えを受け入れますが、これは私が示した例にも触れています。


2
-1この質問は前に尋ねたと回答されました:stackoverflow.com/questions/164527/...
エレメント

メソッド/フィールド/プロパティの長所と短所は長い議論を生む可能性があります。プロパティのいくつかの一般的な用途:プライベート/保護されたフィールドが必要であると同時にそれらを公開したい場合。もう1つの用途は、ステートメントだけでなく、式(必要に応じてアクション)もif()チェック(MSDNごとに)することです。しかし、ユーザーが変数(プロパティ)へのアクセスの背後にある処理コストを常に認識しているわけではないため(つまり、コードが利用できないため)、厳密な理由から、プロパティをベンチマークする必要があります。ああ、そして "ボーナス"あなたはプロパティでポインタを使用することはできません。
mireazma 2016年

回答:


145

プロパティとメソッドの間で選択クラスライブラリを開発するための設計ガイドラインのセクション:

一般に、メソッドはアクションを表し、プロパティはデータを表します。プロパティはフィールドのように使用することを意図しています。つまり、プロパティは計算的に複雑であったり、副作用を引き起こしたりしてはなりません。次のガイドラインに違反していない場合は、メソッドではなくプロパティの使用を検討してください。経験の浅い開発者は、プロパティの方が使いやすいためです。


3
私はその多くに同意しますが、副作用に関する部分は正しくないと思います。たとえば、「色」はオブジェクトのプロパティであることが多く、明らかな副作用(オブジェクトの色の変更)があります。プロパティを変更すると、オブジェクトの状態が変わるという明らかな副作用があります。
Erik Funkenbusch 2009年

46
ミステリーマンが色を変えることは副作用ではなく望ましい効果です。副作用は、一次的なアクションでは意図されていないものです。
ムハンマドハサンカーン

2
@Mystere Man:明確に色を変えることは副作用ではありません、私はこの答えに完全に同意します
アーメッドは

2
「経験の浅い開発者は、プロパティの方が使いやすいからです。」-私が見るように、これはプロパティを公開する唯一の理由です。しかし、私は正しいのでしょうか?
Tsabo 2011

2
プロパティとメソッドの内部実装の違いは何ですか。プロパティが使用されるときはいつでもコールスタックに何かがプッシュされますか?そうでない場合、それは他にどのように扱われますか?
Praveen 14

57

はい、取得と設定だけを行う場合は、プロパティを使用します。

複数のデータメンバーに影響を与える可能性がある複雑な処理を行う場合は、メソッドの方が適しています。または、ゲッターがパラメーターを取る場合、またはセッターが値パラメーター以上のものを取る場合。

中央は灰色の領域で、線が少しぼやけています。厳格な規則はなく、プロパティとメソッドのどちらが適切であるかは、人によって異なる場合があります。重要なことは、あなたがそれをどのように(またはあなたのチームがどのように)行うかと(比較的)一貫していることです。

これらはほとんど互換性がありますが、プロパティは実装が比較的「単純」であることをユーザーに知らせます。ああ、構文はもう少しきれいです。

一般的に言って、私の哲学は、getまたはsetで始まり、(それぞれ)0または1つのパラメーターを受け取るメソッド名を記述し始めると、それがプロパティの主要な候補になるということです。


1
反対票。これは正しくありません。ゲッターまたはセッターの複雑さは、ゲッター/セッターコード内にカプセル化されます。複雑さはまったく関係なく、「複数のデータメンバーに影響する」かどうかも関係ありません非標準または複数のパラメーターがメソッドを必要とすることは事実ですが、そうでない場合、この答えは正確ではありません。
Hal50000 2016年

最初の文ですべてを説明します。ブラボー。
SWIIWII 2017

13

プロパティは、オブジェクトからデータを挿入または取得する方法です。それらは、クラス内の変数またはデータの抽象化を作成します。これらは、Javaのゲッターおよびセッターに似ています。

メソッドは操作をカプセル化します。

一般に、私はプロパティを使用して、データの1ビット、または消費税などのクラスの小さな計算を公開します。これは、ショッピングカート内のアイテムの数とコストから算出されます。

データベースからデータを取得するなど、操作を作成するときにメソッドを使用します。可動部分を持つ操作はすべてメソッドの候補です。

あなたのコード例では、それが含まれているクラスの外側にアクセスする必要がある場合、それをプロパティにラップします:

public Label Title 
{
   get{ return titleLabel;}
   set{ titleLabel = value;}
}

テキストの設定:

Title.Text = "Properties vs Methods";

LabelのTextプロパティのみを設定していた場合、次のようになります。

public string Title 
{
   get{ return titleLabel.Text;}
   set{ titleLabel.Text = value;}
}

テキストの設定:

Title = "Properties vs Methods";

12

オブジェクトの実際のプロパティを設定する場合は、プロパティを使用します。

タスク/機能を実行している場合は、メソッドを使用します。

あなたの例では、それは設定されている明確なプロパティです。

ただし、機能がAppendToLabelに対するものである場合は、メソッドを使用します。


11

MSDNを検索して、メソッドを作成するためのいくつかの優れたガイドラインを提供するプロパティとメソッドのリファレンスを見つけました。

  • 操作は、などの変換Object.ToStringです。
  • この操作は、ユーザーに結果をキャッシュすることを検討する必要があることを伝えたいほど高価です。
  • getアクセサーを使用してプロパティ値を取得すると、目に見える副作用があります。
  • メンバーを続けて2回呼び出すと、異なる結果が生成されます。
  • 実行の順序は重要です。タイプのプロパティは、任意の順序で設定および取得できる必要があることに注意してください。
  • メンバーは静的ですが、変更可能な値を返します。
  • メンバーは配列を返します。配列を返すプロパティは誤解を招く可能性があります。通常、ユーザーが内部状態を変更できないように、内部配列のコピーを返す必要があります。これは、ユーザーがそれをインデックス付きプロパティであると容易に想定できるという事実と相まって、非効率的なコードにつながります。

これは、該当する場合は常に意味があることに同意します。しかし、私が正しいのは、WPFでXAMLバインディングを介してプロパティを使用すると、セッターで適切なアクションを実行する以外に選択肢がないことです。(特に、ComboBoxes、ListBoxesなどの新しいSelectedItemの場合)
Nicolas

9

あなただけの名前を見る必要があります... "プロパティ"。どういう意味ですか?辞書は多くの方法でそれを定義しますが、この場合、「本質的または特有の属性またはものの品質」が最も適しています。

アクションの目的について考えます。あなたは実際、「本質的または特有の属性」を変更または取得していますか?あなたの例では、テキストボックスのプロパティを設定するために関数を使用しています。ちょっとばかげているようですね。

プロパティは実際には関数です。それらはすべてgetXXX()およびsetXXX()にコンパイルされます。構文糖でそれらを隠すだけですが、プロセスに意味的な意味を提供するのは糖です。

属性などのプロパティについて考えます。車には多くの属性があります。色、MPG、モデルなど。すべてのプロパティを設定できるわけではなく、一部は計算可能です。

一方、メソッドはアクションです。GetColorはプロパティである必要があります。GetFile()は関数である必要があります。もう1つの目安として、オブジェクトの状態が変化しない場合は、関数である必要があります。たとえば、CalculatePiToNthDigit(n)は、アタッチされているMathオブジェクトの状態を実際には変更しないため、関数にする必要があります。

これは少し混乱しているかもしれませんが、実際には、オブジェクトとは何か、オブジェクトが何を表すのかを決定することになります。プロパティと関数のどちらであるかわからない場合は、どちらでもかまいません。


9

対称的に、プロパティはオブジェクトの属性です。メソッドはオブジェクトの動作です。

ラベルは属性であり、プロパティにする方が理にかなっています。

オブジェクト指向プログラミングの観点からは、動作の一部であり、単なる属性であるものを明確に理解している必要があります。

車{色、モデル、ブランド}

車にはColor、Model、Brandの各属性があるため、対称的にCarに独自の色を設定するように要求しないため、SetColorまたはSetModelメソッドを使用しても意味がありません。

そのため、プロパティ/メソッドのケースを実際のオブジェクトにマッピングするか、意味論的な観点から見れば、混乱は本当になくなります。



3

1つのパラメーターを持つadd / setメソッドのプロパティを使用することを好みます。パラメータが多い場合は、メソッドを使用します。


3

プロパティは単純なセットのみで、1つのライナーを取得する必要があります。それ以上のもので、それを実際にメソッドに移動する必要があります。複雑なコードは常にメソッド内にある必要があります。


3

変数へのアクセス、つまり個々の変数の取得と設定、またはコントロールでのデータの取得と設定にのみプロパティを使用します。あらゆる種類のデータ操作が必要/実行されるとすぐに、私はメソッドを使用します。


3

設計の問題として、プロパティはクラスオブジェクトのデータまたは属性を表し、Whileメソッドはクラスオブジェクトのアクションまたは動作です。

.Netでは、プロパティの使用には他にも影響があります。

  • プロパティはデータバインディングで使用されますが、get_ / set_メソッドは使用されません。
  • シリアライズの自然なメカニズムとしてのXMLシリアライゼーションのユーザープロパティ。
  • プロパティは、PropertyGridコントロールとインターンICustomTypeDescriptorによってアクセスされます。これは、カスタムライブラリを作成している場合に効果的に使用できます。
  • プロパティは属性によって制御され、アスペクト指向ソフトウェアを設計するためにそれを賢く使用できます。

プロパティの使用に関する誤解(IMHO):

  • 小さな計算を公開するために使用されます:ControlDesigner.SelectionRulesのgetブロックは72行になります!!
  • 内部データ構造を公開するために使用されます:プロパティが内部データメンバーにマップされない場合でも、クラスの属性であれば、プロパティとして使用できます。逆に、クラスプロパティの属性が推奨されていない場合でも、データメンバーのような配列を返す(代わりに、メソッドを使用してメンバーの深いコピーを返す)。

ここの例では、次のようにビジネス上の意味を追加して記述できます。

public String Title
{
    set { Label.Text = text; }
}

2

プロパティは、アクセスが許可されていれば、ビジュアルスタジオのビジュアルデザイナーでアクセスできるため、非常に便利です。

それらは、単に設定して取得しているだけの場合に使用され、おそらく、大量のコードにアクセスしないいくつかの検証を使用します。検証中に複雑なオブジェクトを作成することは簡単ではないので注意してください。

それ以外の方法が推奨されます。

意味論だけではありません。プロパティを使用すると、ビジュアルスタジオのビジュアルデザイナーで奇妙な開始が発生します。

たとえば、クラスのプロパティ内の構成値を取得していました。構成クラスは実際にファイルを開き、SQLクエリを実行してその構成の値を取得します。これにより、アプリケーションで問題が発生しました。構成値を読み取るだけでなく(セッターメソッドを介して)書き込むため、アプリケーションではなく、Visual Studio自体によって構成ファイルが開かれてロックされます。これを修正するには、メソッドに変更する必要がありました。


1

以下は、ビルワーグナーのプロパティとメソッドをいつ使用するかについてのガイドラインの良いセットです

  • これらがすべてtrueの場合は、プロパティを使用します。ゲッターは単純でなければならず、したがって例外をスローする可能性は低くなります。これは、ネットワーク(またはデータベース)アクセスがないことを意味します。どちらかが失敗する可能性があるため、例外がスローされます。
  • それらは互いに依存関係があってはなりません。これには、1つのプロパティの設定と別のプロパティへの影響が含まれることに注意してください。(たとえば、FirstNameプロパティを設定すると、姓と名のプロパティで構成された読み取り専用のFullNameプロパティに影響し、そのような依存関係が示唆されます)
  • それらは任意の順序で設定可能でなければなりません
  • ゲッターには目に見える副作用はありません。このガイドラインは、プロパティでの遅延評価の一部の形式を排除していません。
  • メソッドは常にすぐに戻る必要があります。(これにより、データベースアクセス呼び出し、Webサービス呼び出し、またはその他の同様の操作を行うプロパティが除外されることに注意してください)。
  • メンバーが配列を返す場合は、メソッドを使用します。
  • (介入コードなしで)ゲッターを繰り返し呼び出すと、同じ値が返されます。
  • (同じ値で)セッターを繰り返し呼び出しても、1回の呼び出しと違いはありません。

  • getは、内部データ構造への参照を返しません(項目23を参照)。メソッドはディープコピーを返すことができ、この問題を回避できます。

*重複した質問に対する私の回答から引用。


ここで最高評価と承認された回答stackoverflow.com/a/1294189/1551 なぜ反対票か
クリスバランス

2
私はパーティーに少し遅れていると思いますが、その反対投票はおそらくあなたがあなたの回答をコピーして貼り付けたという事実のために起こりました。コピー貼り付けにより、この質問は基本的に他の質問の複製であることを認めました。そのため、回答するのではなく、重複としてフラグを立てる必要があります。重複する質問の処理方法については、メタに関する記事を参照することをお勧めします。
ジョシュア

0

これは簡単です。

1:フィールドに格納する前にデータを検証する必要がある場合にプロパティを使用します。したがって、この方法でプロパティはフィールドをカプセル化します。フィールドをそのままにしておくと、パブリックエンドユーザーがビジネス要件に応じて有効または無効になる可能性のある任意の値を割り当てる可能性があるためです。たとえば、年齢は18を超える必要があります。したがって、値が対応するフィールドを格納する前に、その有効性を確認する必要があります。このようにして、プロパティはデータを表します。

2:パラメータとしてデータを提供し、メソッドが提供された値に基づいて処理を実行し、処理された値を出力として返す場合などに、メソッドを使用します。または、この計算によって一部のフィールドの値を変更したい場合。「このようにしてメソッドはアクションを表します」。


-1

私はjavaから来て、しばらくget .. set ..メソッドを使いました。

コードを書くとき、「このデータへのアクセスは簡単ですか、それとも重いプロセスが必要ですか?」物事が変わる可能性があるため(今日、このプロパティを取得するのは簡単ですが、tomonrowはある程度または重いプロセスを必要とする場合があります)。

今日私はSetAge(int age)tomonrowメソッドを持っています。また、誕生日を使用して年齢を計算するSetAge(date birthdate)メソッドも持っています。

コンパイラがgetおよびsetのプロパティを変換することに非常にがっかりしましたが、Get ...メソッドとSet ..メソッドを同じものと見なしていません。

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