web-dev-qa-db-ja.com

プロパティとメソッド

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

私たちはこの議論に忙しく、プロパティを使うべきかメソッドを使うべきかが議論の余地がある分野を見つけました。 1つの例は次のとおりです。

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

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

最も一般的かつ包括的な答えを受け入れますが、それはまた、私が与えた例にも触れます。

122
Trumpi

クラスライブラリ開発の設計ガイドラインの プロパティとメソッドの選択 セクションから:

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

129
Ken Browning

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

複数のデータメンバーに影響を与える可能性のある複雑なことをしている場合は、メソッドがより適切です。または、ゲッターがパラメーターを取る場合、またはセッターが値パラメーター以上を受け取る場合。

中央には灰色の領域があり、線が少しぼやけている場合があります。厳格なルールはありません。また、プロパティまたはメソッドのどちらを使用するかについて、異なる人々が意見を異にする場合があります。重要なのは、yoの実行方法(またはチームの実行方法)と(比較的)一貫性を保つことです。

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

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

52
cletus

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

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

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

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

12
Robin Day

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

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

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

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

あなたのコード例では、クラスを含む外部からアクセスする必要がある場合、プロパティでラップします:

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

テキストの設定:

Title.Text = "Properties vs Methods";

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

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

テキストの設定:

Title = "Properties vs Methods";
12
Chuck Conway

MSDNを検索すると、メソッドを作成するための優れたガイドラインを提供する Properties vs Methods に関するリファレンスが見つかりました。

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

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

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

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

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

車にはColor、Model、およびBrand属性があります。したがって、メソッドSetColorまたはSetModelを持つことは意味がありません。これは、Carに独自の色を設定するように要求しないためです。

そのため、プロパティ/メソッドのケースを実際のオブジェクトにマッピングしたり、シンボリックな視点から見たりすると、混乱は本当になくなります。

9

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

アクションの目的について考えてください。実際、あなたは「本質的または特徴的な属性」を変更または取得していますか?この例では、関数を使用してテキストボックスのプロパティを設定しています。それは一種のばかげているように見えますか?

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

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

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

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

8

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

3
abatishchev

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

3
Duke of Muppets

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

3
Marcus L

また、プロパティの大きなメリットは、デバッグ中にVisual Studioでプロパティの値を表示できることです。

3
David Karlaš

プロパティは、Visual Studioのビジュアルデザイナーでアクセスできるので、アクセスできるのであれば、本当に素晴らしいです。

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

他の方法はすべて推奨される方法です。

セマンティクスだけではありません。不適切なプロパティの使用は、Visual Studioのビジュアルデザイナーで発生します。

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

2
Jeremy Edwards

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

.Netの世界では、プロパティの使用には他の意味があります。

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

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

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

ここの例では、ビジネス上の意味がより大きくなるように記述できます。

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

Bill Wagner のプロパティとメソッドをいつ使用するかについて、ガイドラインの適切なセットを次に示します。

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

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

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

1
Chris Ballance

これは簡単です。

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

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

0
Saurabh Mishra