1

次のようなプロパティがあるとします。

Person person1;


public Person Captin{
    get{
        return person1;
    }
    set{
        person1 = value;
    }
}

public void SomeFunction(){
    Captin.name = "Hook"
}

この場合、プロパティに名前を設定すると、フックの新しい名前が person1 の基になる値に適用されることがわかります。私たちの実装が少し違っていたらどうなるでしょうか:

public Person Captin{
    get{
        return ReadCaptinFromDisk();
    }
    set{
        WriteCaptinToDisk(value);
    }
}

public void SomeFunction(){
    Captin.name = "Hook"
}

この場合、基になる値を適切に設定するには、Captin.name への割り当ての一部として Captin の設定コードを呼び出す必要があります。

パラメータ セット コードがフィールドの割り当てでセットを呼び出すかどうか、またはプロパティ参照でメソッド呼び出しを行うかどうかを知りたいです。特に、値をディスク (など) に伝搬する必要があるこの種の状況では。

4

4 に答える 4

4

プロパティ Captin にアクセスするたびに、ディスクから読み取られます。ただし、プロパティ「name」を変更すると、ディスクに書き込まれません。次のような場合にのみディスクに書き込みます

public void SomeFunction() {
   Person p = Captin;
   p.name = "Hook";
   Captin = p;
}
于 2008-11-20T16:33:50.033 に答える
1

プロパティのセッターは、誰かが実際にプロパティに直接割り当てた場合にのみ呼び出されます。

あなたのコードが大丈夫かどうかに関しては:それはドキュメントの問題です。

変更可能なものを返すプロパティがある場合は常に、そのプロパティに対してどのような変更が行われるかを示す必要があります。「実際の」データのコピーを返しますか、それとも実際のデータ自体ですか。これは、プロパティ(または通常のメソッド)が何らかのコレクションを返すときに頻繁に発生します-それは変更可能ですか?変更するとどうなりますか?

返されるデータが単なるコピーであり、変更がどこにも反映されないことを説明するプロパティを文書化する場合、それは問題ありません。あいまいなままにしておくと、問題が発生します。

もちろん、不変性はこれらの懸念を取り除きます...

于 2008-11-20T17:15:14.160 に答える
1

@Joeが指摘しているように、ディスクには書き込まれません。セッターではなくゲッターのみを使用しているためだと付け加えたいと思います。@Joeの例では両方を使用しています。

私の意見では、これはゲッターの本当に悪い使い方であり、関心の分離に違反しています。データの永続化を処理するデータ層が必要です。このロジックは、ビジネス オブジェクトに含めるべきではありません。

于 2008-11-20T16:41:24.370 に答える
1

クラスタイプの変数、パラメーター、フィールド、戻り値、またはその他のそのような保存場所は、「オブジェクト ID」を保持していると考えるべきです。あるオブジェクトに、 field によってサポートされる何らかのクラス タイプのFoo呼び出されたプロパティがあり、 "object id#24601"を保持している場合、ステートメントはオブジェクト #24601 のセッターを "George" の値で呼び出します。このステートメントはオブジェクト自体を変更しないことに注意してください (そのフィールドは、ステートメントの実行前に「object id#24601」を保持し、その後も保持します)。ただし、オブジェクト #24601 に影響を与える可能性があります。Bar_Bar_BarFoo.Bar.Text = "George"TextFoo_Bar

構造体型の格納場所は、そのすべてのフィールド (パブリックとプライベートの両方) の内容を保持していると考える必要があります。が type (構造体)Foo.Bozのプロパティであり、バッキング フィールド である場合、 へのアクセスにより type の新しい一時インスタンスが作成され、そのすべてのフィールドが のフィールドからコピーされます。読み取りを試みると、のすべてのフィールドが一時インスタンスにコピーされ、そのインスタンスのフィールドにアクセスされます。Rectangle_BozFoo.BozRectangleFoo._BozFoo.Boz.X_BozX

一部の非常に古くて邪悪な C# コンパイラは、 のようなコードを解釈Foo.Boz.X = 5;Rectangle temp; temp.X = 5;、結果の temp の値を破棄しますが、警告は発行しないことに注意してください。このようなコンパイラの動作により、一部の人々は構造体を「不変」にして、そのようなコードが偽の動作を生成するのではなくコンパイラ エラーを生成するように宣言しました。X残念なことに、まともなコンパイラなら可変フィールドであってもそのようなコードを禁止するという事実にもかかわらず、その信念は今日まで続いています。

変更可能な構造体型のプロパティを更新する適切な慣用的な方法は次のとおりです。

  Rectangle temp = MyListOFRectangles[5];
  temp.X = 5;
  MyListOFRectangles[5] = temp;

Rectangleが という名前のパブリック整数フィールドを持っていることがわかっていて、 がXMyListOfRectanglesある場合、の他のプロパティ、コンストラクタなどList<Rectangle>について知る必要はありません。上記のコードが変更されるが、他のプロパティには影響しないことを知るためにの、またはのプロパティ。素晴らしく、明確で、簡単です。公開フィールド構造体を使用すると、他の種類のデータ型とは異なり、明確で一貫性のある方法で値を部分的に編集できます。RectangleMyListOfRectangles[5].XMyListOfRectangles[5]MyListOfRectangles[4]

于 2012-07-18T18:42:10.857 に答える