3

プライベート構造体をインスタンス化する「アダプタ」基本クラスを作成しています。構造体は、抽象Configure()メソッドを介して継承者に公開されるため、継承者はプロパティを設定できます。次のように実装します。

public abstract class PaymentAdapter {

    private PaymentObject p = new PaymentObject();

    protected PaymentObject CreditCardPayment {
        get { return p; }
    }

    protected abstract void Configure(PaymentObject payment);

    public MyResponse ProcessPayment() {
        // Run the adapter's setup
        Configure(p);

        // Charge the customer
        var chargeResult = p.DoSomething();

        return new MyResponse {
            MyResult = chargeResult
        };
    }
}

注意深い人は、次の行に注意が必要なものがわかります。

protected abstract void Configure(PaymentObject payment);

具体的なクラスでオーバーライドされると、このメソッドは(ほとんど)コンシューマーに構造体のプロパティを直接変更する機会を与えます。これは望ましい結果です。

私の質問は-ref引数を使用するか、voidをPaymentObjectに変更して、コンシューマーがインスタンスを返すようにする必要がありますか?

方法1:

protected abstract PaymentObject Configure(PaymentObject payment);

方法2:

protected abstract void Configure(ref PaymentObject payment);

したがって、クラスを継承する場合、コンシューマーは次のことを行う必要があります。

方法1:

public class MyConsumer : PaymentAdapter {
    #region Overrides of PaymentAdapter

    protected override PaymentObject Configure(PaymentObject payment) {
        payment.AProperty = "Something";
            return payment;
    }

    #endregion
}

方法2:

public class MyConsumer : PaymentAdapter {
    #region Overrides of PaymentAdapter

    protected override void Configure(ref PaymentObject payment) {
        payment.AProperty = "Something";
    }

    #endregion
}

構文のわずかな変更は別として、他に何か違いはありますか?これは好みのことですか、それとも一方を他方よりも使用することには見えない利点がありますか?

コードが少し少ないので、メソッドからオブジェクトを排他的に返す長年の経験とは対照的に、「ref」メソッドを使用する傾向があります。これは、ref引数の完璧なケースのようです。これにより、コンシューマーの作業が少し簡単になり、オブジェクトをあちこちに設定していないことを意味します。

4

4 に答える 4

2

参照型はデフォルトで参照によって渡されるため、refここでキーワードを使用する必要はありません。

タイプがaのStruct場合、構造体は不変である必要があるため、必ずreturnステートメントを使用する必要があります(なぜ、可変構造体が「悪」であるのか、C#構造体が不変であるのかについての回答を読んでください) 。

于 2013-02-20T12:56:35.813 に答える
1

が構造体の場合PaymentObject、メソッド2の方が高速です。これは、メソッド1では、最初にのインスタンスをPaymentObjectコピーし、そのコピーを変更して、そのコピーのコピーを返すためです。私が行ったベンチマーク(64バイトの構造体の場合、Linux Mint 14のMono)では、2番目の方法は最大3倍高速です。

ただし、2番目の方法にはいくつかの欠点があります。C#には、問題のメソッドまたはクラスに属していない構造体を直接変更してはならない、ある種の不文律があります。これは主に、インターフェイスに関するスレッド化と複雑化に関係しています。

したがって、パフォーマンスが本当に必要で、スレッド化の複雑さを心配する必要がない限り、最初の方法を選択します。

于 2013-02-20T13:14:26.990 に答える
0

実際のPaymentObjectのプロパティのみを変更する場合は、refを使用する必要はありません。変更されたのと同じオブジェクトのままになります。

私はあなたが一緒に行くことをお勧めします

protected abstract void Configure(PaymentObject payment);

変更される実際のオブジェクトであるため、オブジェクトを返す必要はありません。

于 2013-02-20T12:59:24.890 に答える
0

この場合、「ref」パラメータを選択する必要があると思います。'ref'を使用すると、'CreditCardPayment'プロパティからPaymentObject値を取得することもできます。ただし、オブジェクトを返すと、「ProcessPayment」メソッド内でのみオブジェクトが返され、「CreditCardPayment」プロパティから実際の値を取得することはできません。

于 2013-02-20T13:49:00.453 に答える