1

したがって、次の方法で定義された構造体があります。

    public struct Item
{
    public string _name { get; set; }
    public double _weight
    {
        get 
        {
            return _weight;
        }
        set
        {
            _weight = value;

            //Shipping cost is 100% dependent on weight. Recalculate it now.
            _shippingCost = 3.25m * (decimal)_weight;

            //Retail price is partially dependent on shipping cost and thus on weight as well.  Make sure retail price stays up to date.
            _retailPrice = 1.7m * _wholesalePrice * _shippingCost;
        }
     }
    public decimal _wholesalePrice
    {
        get
        {
            return _wholesalePrice;
        }
        set
        {
            //Retail price is partially determined by wholesale price.  Make sure  retail price stays up to date.
            _retailPrice = 1.7m * _wholesalePrice * _shippingCost;
        }
    }
    public int _quantity { get; set; }
    public decimal _shippingCost { get; private set; }
    public decimal _retailPrice { get; private set; }


    public Item(string name, double weight, decimal wholesalePrice, int quantity) : this()
    {
        _name = name;
        _weight = weight;
        _wholesalePrice = wholesalePrice;
        _quantity = quantity;
    }
//More stuff

別のクラスに Item のインスタンスもあります。次のコマンドで weight プロパティを呼び出そうとすると、プログラムがクラッシュします。

currentUIItem._weight = formattedWeight;

説明的なエラーは提供されません。この時点で、 currentUIItem がパラメーターなしのデフォルト コンストラクターで新しく作成されていることに注意してください。さて、ここが奇妙な部分です。重みの set プロパティのカスタム実装を削除し、それを汎用の { get; に置き換えると、設定; }、割り当ては問題なく機能します。

ここで何が起こっているか知っている人はいますか?これは、クラスでうまく機能する構造体の癖ですか?

4

4 に答える 4

3

プロパティのメソッドにプロパティへの再帰呼び出しが_weightあります。_weightset

于 2012-07-29T20:50:46.447 に答える
2

無限再帰があるため、これにより StackOverflowException が発生するようです。

セッターにブレークポイントを設定した場合:

public double _weight
{
    set
    {
        _weight = value;
    }
 }

ブレークポイントがヒットし続けていることがわかります。これは、setter が _weight に値を設定しようとするためです。しかし、_weight は変数ではありません... その値を設定しようとすると、setter メソッドにコールバックするだけです。これは無限に起こり続けます。同じことが _wholesalePrice プロパティにも当てはまります...おそらく、次のようなものが必要になるでしょう:

public struct Item
{
    public string _name { get; set; }

    private double _weightInternal;
    public double _weight
    {
        get 
        {
            return _weightInternal;
        }
        set
        {
            _weightInternal = value;

            //Shipping cost is 100% dependent on weight. Recalculate it now.
            _shippingCost = 3.25m * (decimal)_weightInternal;

            //Retail price is partially dependent on shipping cost and thus on weight as well.  Make sure retail price stays up to date.
            _retailPrice = 1.7m * _wholesalePriceInternal * _shippingCost;
        }
    }

    private decimal _wholesalePriceInternal;
    public decimal _wholesalePrice
    {
        get
        {
            return _wholesalePriceInternal;
        }
        set
        {
            //Retail price is partially determined by wholesale price.  Make sure  retail price stays up to date.
            _wholesalePriceInternal = value;
            _retailPrice = 1.7m * _wholesalePriceInternal * _shippingCost;
        }
    }
    public int _quantity { get; set; }
    public decimal _shippingCost { get; private set; }
    public decimal _retailPrice { get; private set; }


    public Item(string name, double weight, decimal wholesalePrice, int quantity) : this()
    {
        _name = name;
        _weightInternal = weight;
        _wholesalePriceInternal = wholesalePrice;
        _quantity = quantity;
    }
    //More stuff
}
于 2012-07-29T20:52:40.910 に答える
1

プロパティのセッターが_weight自己を再帰的に呼び出しており、StackOverFlow 例外が発生しています

これを修正する最も簡単な方法は、このようにプロパティのバッキング フィールドを持つことです。

private double  _weight;
public double Weight
    {
        get 
        {
            return _weight;
        }
        set
        {
            _weight = value;

            //Shipping cost is 100% dependent on weight. Recalculate it now.
            _shippingCost = 3.25m * (decimal)_weight;

            //Retail price is partially dependent on shipping cost and thus on weight as well.  Make sure retail price stays up to date.
            _retailPrice = 1.7m * _wholesalePrice * _shippingCost;
        }
     }
于 2012-07-29T20:53:51.757 に答える
1

_weight のセッターでは、_weight を設定しようとしているため、無限再帰が発生します。

次のようなものを試してください (小売および送料に関する追加のロジックは含めません)。

private double _weight;
public double Weight
{
     get { return _weight; }
     set { _weight = value; }
}

を使用get; set;すると、バッキング フィールドを自動的に生成するようにコンパイラに指示され、上記のコードと同じ効果があります。

使用される命名規則にも注意してください。フィールド (_weight) にはアンダースコアが前に付けられ、常に非公開にする必要があります。外部の世界は、プロパティ (重み) を使用してフィールドと相互作用します。このパターンは、.NET フレームワーク全体に配置されています。「C# のフィールドとプロパティの違いは何ですか?」を参照してください。詳細については。

于 2012-07-29T20:55:20.003 に答える