2

今日、構造体を使用して不意を突かれた問題に遭遇しました。誰かが私のためにそれを明らかにしてくれることを望んでいました。

次のように定義された構造体があります。

public struct PaymentDetail
{
    public Decimal Amount{get;set;}
    public string CheckNumber{get;set;}
    public PaymentType PaymentType{get;set;}
}

この情報を含むクラスがあります

public class Transaction
{
    public PaymentDetail Payment{get;}
}

このような基本的なプロパティを設定したいプレゼンテーションモデルがあります

public class ViewModel
{
    public Decimal Amount
    {
        get{return _Transaction.PaymentDetail.Amount;}
        set
        {
             //This is the offending line of code
             _Transaction.PaymentDetail.Amount = value;
             RaisePropertyChanged("Amount");
        }
    }
}

奇妙なのは、次のように Payment プロパティを public フィールドに変更すると、これを機能させることができるということです。

public class Transaction
{
    public PaymentDetail Payment;
}

これを引き起こしている構造体について私が理解していないことが明らかにあります。これは悪い考えですか?より良い方法はありますか?私は何を間違っていますか?

4

2 に答える 2

6

まず、変更可能な構造体(つまり、構築後にセッターなどを介して値を変更できる構造体)を使用しないでください。それがここでの混乱の主な原因です。

ポイントは; (のような)プロパティを呼び出すと、(ローカルスタック領域にある)値のコピーPaymentを取得します。クラスの場合、それは参照のコピーです(問題ありません)。構造体の場合、それは構造体自体のコピーです。その値への変更はすべて破棄されるため、コンパイラーはデータの損失を防ぎます。

パブリックフィールドの場合、元の値を直接変更しているため、問題ありません。しかし、構造体を変更することは実際には良い考えではありません。

PaymentDetailクラスを作る; それがここでの正しい解決策です...

.NETでは、構造体は「動作のないオブジェクト」ではなく、「値型」です。「通貨/値のペア」、「時間範囲」などのようなものは、有効な構造体を作成する可能性がありますが、そうではありませんPaymentDetail

于 2009-03-25T13:02:47.650 に答える
-3

これはおそらく、Paymentをセッターではなく読み取り専用として公開しているためです。構造体は値型であるため、構造体が読み取り専用の場合、構造体にプロパティを設定することはできません。

セッターを追加すると、問題が解決するはずです。

また、PaymentDetailをクラスに変更することも検討します。構造体は、非常に基本的な値である場合にのみ使用します。特に1つが文字列である場合、このような3つのプロパティを持つものはクラスである必要があります。

于 2009-03-25T13:08:56.107 に答える