25

次のようにゲッターでオブジェクトを作成してみましょう。

public class Class1
{
       public string Id { get; set; }
       public string Oz { get; set; }
       public string Poznamka { get; set; }

       public Object object
       {
             get
             {
                  // maybe some more code
                  return new Object { Id = Id, poznamla = Poznamka, Oz = OZ };
             }
        }
 }

それとも、オブジェクトを作成して返すメソッドを作成する必要がありますか?

4

14 に答える 14

22

はい、それは悪い習慣です。

理想的には、getter は何も変更したり作成したりすべきではありません (遅延読み込みは別として、それでもコードが不明瞭になると思います...)。そうすることで、意図しない副作用のリスクを最小限に抑えることができます。

于 2010-01-20T13:35:34.403 に答える
16

プロパティはフィールドのように見えますが、メソッドです。これは、驚異的な量の混乱を引き起こすことが知られています。プログラマーがフィールドにアクセスしているように見えるコードを見た場合、プログラマーは、プロパティに対して当てはまらない可能性がある多くの仮定を立てています。そのため、一般的なプロパティ設計ガイドラインがいくつかあります。

  1. プロパティ ゲッターから異なる値を返さないようにします。続けて複数回呼び出された場合、プロパティ メソッドは毎回異なる値を返すことがあります。フィールドは毎回同じ値を返します。

  2. プロパティ メソッドは、追加のメモリを必要とするか、実際にはオブジェクトの状態の一部ではない何かへの参照を返す場合があるため、返されたオブジェクトを変更しても元のオブジェクトには影響しません。フィールドを照会すると、元のオブジェクトの状態の一部であることが保証されているオブジェクトへの参照が常に返されます。コピーを返すプロパティを操作すると、開発者が非常に混乱する可能性があり、この特性はドキュメント化されていないことがよくあります。

  3. プロパティを out または ref パラメーターとしてメソッドに渡すことはできないと考えてください。フィールドはできます。

  4. 長時間実行されるプロパティ ゲッターは避けてください。プロパティ メソッドの実行には時間がかかる場合があります。フィールド アクセスは常にすぐに完了します。

  5. ゲッターから例外をスローしないようにします。

  6. プロパティ セッターが例外をスローした場合、以前の値を保持する

  7. 観察可能な副作用を避ける。

  8. オブジェクトが一時的に無効な状態になる場合でも、プロパティを任意の順序で設定できるようにします。

ソース

C# による CLR」、Jeffrey Richter。第9章 インテリジェントなプロパティーの定義

Framework Design Guidelines」第 2 版、Brad Abrams、Krzysztof Cwalina、第 5.2 章 プロパティの設計

于 2010-01-20T18:04:20.293 に答える
8

アクセスされるたびにゲッターに新しいオブジェクトを作成させたい場合は、それがその方法です。通常、このパターンはFactory Methodと呼ばれます。

ただし、これは通常、プロパティ (つまり、ゲッターとセッター) では必要ないため、悪い習慣と見なされます。

于 2010-01-20T13:37:09.767 に答える
4

はい、そうです...外部からは、プロパティまたはフィールドにアクセスするかどうかに関係なく、透明でなければなりません...

フィールドまたはプロパティから 2 回読み取る場合、次の 2 つのことが予想されます。

  • オブジェクトの (外部) 動作への影響はありません
  • 同じ結果が得られます

私は C# の本当の知識はありませんが、次のことで私の主張が明確になることを願っています。このように始めましょう:

Object o1 = myInst.object;
Object o2 = myInst.object;
o1.poznamka = "some note";

フィールドの場合、次のような条件が true になります。

o1 == o2;
o2.poznamka == "some note";

呼び出されるたびに新しいオブジェクトを返すゲッターでプロパティを使用する場合、両方の条件が false になります ...

あなたのゲッターは、インスタンスの一時的なスナップショットを生成することを意図しているようです...それがあなたがしたいことであれば、それを単純な方法にするよりも...あいまいさを避けます...

于 2010-01-20T14:29:41.097 に答える
2

プロパティは、すべての意図と目的に対して、フィールドのように機能する必要があります。つまり、例外がスローされず、新しいオブジェクトが作成されないことを意味します (そのため、プロパティがループで使用されている場合に不要なオブジェクトを大量に作成することはありません)。

代わりにラッパー クラスなどを使用してください。

于 2010-01-20T13:38:00.547 に答える
2

私によると、何かが「プロパティ」である場合、ゲッターはオブジェクトに関連するプロパティ (基本的には既に存在するデータ) を返す必要があります。

あなたの場合、その時点でそのオブジェクトのプロパティではないものを返しています。オブジェクトのプロパティを返すのではなく、何らかのアクションの結果を返します。

代わりに GetMyObject() のようなメソッドを使用します。特に「アクション」が発生する場合は、ほとんどの場合、プロパティ名よりもメソッドを使用する方がよいと思います。

そして、あなたのコードに詳しくない他の開発者があなたのプロパティを見た後に何を期待するか想像してみてください。

于 2010-01-20T14:36:10.427 に答える
1

簡単にテストできるコードを作成するには、オブジェクトの初期化の分離を維持する必要があります。

つまり、テストケースでは、特定の項目のテストを保留していません。

Houseオブジェクトのように、キッチンオブジェクトに関連するものは何もテストしたくありません。そして、あなたは庭だけをテストします。したがって、ハウスクラスを開始し、一部のコンストラクターまたはゲッターでオブジェクトを開始している間は、テストをサポートする適切なコーディングを行うことはできません。

于 2010-01-20T19:14:24.547 に答える
1

既に作成されたコメントは別として、プロパティを介してフィールドを遅延読み込みすると、実際のデバッグの頭痛の種に遭遇する可能性があります。

私はクラスを持っていた

private Collection<int> moo;

public Collection<int> Moo
{
  get 
  {
    if (this.moo == null) this.moo = new Collection<int>();
    return this.moo;
  }
}

次に、クラスのどこかに、参照するパブリックメソッドがありました

this.moo.Add(baa);

インスタンス化されていることを確認せずに。

予想どおり、null 参照例外がスローされました。ただし、例外は UI スレッド上にあったため、どこから来たのかすぐにはわかりません。トレースを開始し、トレースするたびにエラーが消えました。

しばらくの間、私は自分が頭がおかしくなっていると思ったことを認めなければなりません。デバッガ - エラーなし。ランタイムエラー。後で頭を悩ませているうちにエラーを発見し、Visual Studio デバッガーがクラスのパブリック プロパティを表示するときにコレクションをインスタンス化していることに気付きました。

于 2010-01-21T16:14:29.570 に答える
1

プロパティは、計算フィールドを表現するための便利な方法です。

値自体がどのように到達したかに関係なく、オブジェクトに関する何かを表す必要があります。たとえば、問題のオブジェクトが請求書である場合、各項目のコストを合計し、合計を返す必要がある場合があります。

オブジェクトのコピーを返すことはオブジェクトを説明するものではないため、質問に書かれていることはその規則を破っています。オブジェクトの状態を明示的に変更せずに、プロパティの呼び出し間で戻り値が変化する場合、オブジェクト モデルは壊れています。

一般論として言えば、このような新しいオブジェクトを返すことはほぼ常に規則を破ることになるので (今のところ反例は思いつきません)、それは悪い習慣だと言えます。

また、プロパティを簡単かつ無邪気に複数回呼び出して、同じコードを実行してしまう (遅くないことを願っています) プロパティの落とし穴もあります。

于 2010-01-20T15:09:17.217 に答える
0

せいぜいstructs には許容範囲かもしれません。参照型の場合、遅延読み込みパターンを使用して 1 回だけ行われる場合にのみ、ゲッターで新しいオブジェクトを作成します。

于 2010-01-20T13:37:35.620 に答える
0

ゲッターの使い方次第です。遅延読み込み用のこの種のコードを含めるのに最適な場所です。

于 2010-01-20T13:37:51.870 に答える
0

それは悪い習慣です。あなたの例では、プロパティObjectにアクセスするたびに同じことを期待できるはずです。object

于 2010-01-20T13:38:21.870 に答える
0

あなたが持っているように、それは悪いですが、ここで読むことができる遅延読み込みと呼ばれる許容される慣行に似ています。

http://www.aspcode.net/Lazy-loading-of-structures-in-C-howto-part-8.aspx

于 2010-01-20T13:39:10.120 に答える
0

それは悪い習慣です。しかし、オブジェクトを getter と setter の束として考えている場合は、このトピックに関する古典的な議論を確認する必要があります。

一部の人々が言及したように、遅延読み込みがそうする理由になる可能性があります。ここでモデル化している実際のビジネス ロジックによって異なります。読みやすさのために別のメソッドを作成する必要がありますが、オブジェクトを作成するコードが単純な場合は、間接化を回避できます。

于 2010-01-20T13:41:58.793 に答える