0

これは私のコードです:

class StockItem
{
    internal float CostPrice;
    internal string Description;
    internal static int LastStockNumber = 10000;
    internal int StockNumber;

    public StockItem(int StockNumber, string Description, float CostPrice): this(Description, CostPrice)
    {
        this.StockNumber = StockNumber;
    }

    public StockItem(string Description, float CostPrice)
    {
        LastStockNumber++;
        this.StockNumber = LastStockNumber;
        this.CostPrice = CostPrice;
        this.Description = Description;
    }

    public float GetCostPrice()
    {
        return CostPrice;
    }

    public virtual string Print() //is virtual (Polymorphic)
    {
        string Output = "";
        Output += "\r\n\r\n";
        Output += "Stock Item: ";
        Output += "\r\n";
        Output += "Stock No: " + StockNumber;
        Output += "\r\n";
        Output += "Desc: " + Description;
        Output += "\r\n";
        Output += "Cost: " + CostPrice;
        Output += "\r\n";
        return Output;
      }
    }
}

class HeavyStockItem : StockItem
{
    internal float Weight;

    public HeavyStockItem(int StockNumber, string Description, float CostPrice, float Weight)
        : base(StockNumber, Description, CostPrice)
    {
        this.Weight = Weight;
    }

    public HeavyStockItem(string Description, float CostPrice, float Weight)
        : base(Description, CostPrice)
    {
        LastStockNumber++;
        this.StockNumber = LastStockNumber;
        this.Weight = Weight;
    }

    public float GetWeight()
    {
        return Weight;
    }

    public override String Print() //overriding StockItem.Print and adds wieght to the bottom 
    {
        string Output = "";
        Output += base.Print();
        Output += "Weight: " + Weight + "\r\n";
        return Output;
      }
    }
}

class CarEngine : HeavyStockItem
{
    internal string EngineNumber;

    public CarEngine(int StockNumber, string Description, float CostPrice, float Weight, string EngineNumber)
        : base(StockNumber, Description, CostPrice, Weight)
    {
        this.EngineNumber = EngineNumber;
    }

    public CarEngine(string Description, float CostPrice, float Weight, string EngineNumber)
        : base(Description, CostPrice, Weight)
    {
        LastStockNumber++;
        this.StockNumber = LastStockNumber;
    }

    public override String Print() //overriding StockItem.Print and adds engine number to the bottom 
    {
        string Output = "";
        Output += base.Print();
        Output += "EngineNumber: " + EngineNumber + "\r\n";
        return Output;
    }
  }
}

public partial class Form1 : Form
{
    StockItem StockItem1;
    CarEngine StockItem2;
    CarEngine StockItem3;
    StockItem StockItem4;
    HeavyStockItem StockItem5;

    private void ShowItem (StockItem PrintStockItem)
    {
        txtOutput.Text += PrintStockItem.Print();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        StockItem1 = new StockItem(StockItem.LastStockNumber, "Scrediwer set", 42);
        StockItem2 = new CarEngine(8025, "MazdaB6T", 1252, 800, "Z4537298D");
        StockItem3 = new CarEngine(StockItem.LastStockNumber, "Holden 308", 958, 1104, "P74623854S");
        StockItem4 = new StockItem(8002, "Trolley Jack", 127);
        StockItem5 = new HeavyStockItem(HeavyStockItem.LastStockNumber, "JD Caterpillar Track", 3820, 2830);
    }

    private void btnList_Click(object sender, EventArgs e) //polymorfic call
    {
        ShowItem(StockItem1);
        ShowItem(StockItem2);
        ShowItem(StockItem3);
        ShowItem(StockItem4);
        ShowItem(StockItem5);
    }
  }
}

これは私の出力です:

Stock Item: 
Stock No: 10000
Desc: Scrediwer set
Cost: 42

Stock Item: 
Stock No: 8025
Desc: MazdaB6T
Cost: 1252
Weight: 800
EngineNumber: Z4537298D

Stock Item: 
Stock No: 10002
Desc: Holden 308
Cost: 958
Weight: 1104
EngineNumber: P74623854S

Stock Item: 
Stock No: 8002
Desc: Trolley Jack
Cost: 127

Stock Item: 
Stock No: 10004
Desc: JD Caterpillar Track
Cost: 3820
Weight: 2830

私の質問は:

アイテム 1、3、および 5 の在庫番号を 10000、10001、および 10002 にする代わりに、上記のように取得しています。なぜ理解できないのですか?

4

2 に答える 2

1

StockItem特定の StockNumber を受け入れるコンストラクターが、インクリメントする他のコンストラクターを呼び出していますLastStockNumberStockItemしたがって、 のインスタンス(または から派生したものStockItem)を作成するたびLastStockNumberに、コンストラクターで在庫数が指定されていても、 がインクリメントされます。

実際、LastStockNumber多くのコンストラクターでインクリメントしているため、一部のタイプのオブジェクトを作成すると、少なくとも 2 回インクリメントされます。


編集:

これを修正する方法についてStockItemは、LastStockNumber を使用するコンストラクターを変更して、他のコンストラクターを呼び出すのではなく、価格と説明自体を設定することから始めます。

public StockItem(int StockNumber, string Description, float CostPrice)
{
    this.StockNumber = StockNumber;
    this.CostPrice = CostPrice;
    this.Description = Description;
}

LastStockNumber次に、派生クラスのコンストラクターでインクリメントする他のすべての場所を削除します。

LastStockNumberまた、プライベートにする必要があります。これらの変更を行った後、そのままの方法でオブジェクトを作成し続けると、オブジェクトを作成するLastStockNumberときに常にストック番号を指定しているため、 が増加することはありません。

于 2015-01-06T05:10:58.557 に答える
0

あなたのコンストラクターCarEngineが呼び出している、

    StockItem2 = new CarEngine(8025, "MazdaB6T", 1252, 800, "Z4537298D");

public CarEngine(int StockNumber, string Description, float CostPrice, 
                 float Weight, string EngineNumber)
    : base(StockNumber, Description, CostPrice, Weight)

次に、以下の基本クラス コンストラクターを呼び出します。

public StockItem(int StockNumber, string Description, float CostPrice): this(Description, CostPrice)
{
   this.StockNumber = StockNumber;

StockNumber を直接設定します。

同様に、トロリーは同じ StockItem コンストラクターを使用して直接構築されます。

  StockItem4 = new StockItem(8002, "Trolley Jack", 127);

一見すると、もう一方の StockItem コンストラクター、つまり静的カウンターをインクリメントするコンストラクターを呼び出したかったようです。

 public StockItem(string Description, float CostPrice)

余談ですが、浮動小数点変数を使用して通貨を格納すると、丸めの問題が発生する可能性が高いことに注意してくださいfloat CostPrice。代わりに使用することをお勧めしdecimalます。

編集

FWIW 基本StockItemクラスを次のように再設計して、プロパティをカプセル化し、増分在庫数の割り当てを制御します。また、静的変数はスレッド セーフの問題を起こしやすいことにも注意してください。

internal class StockItem
{
    // Private to prevent externals + subclasses from mutating this
    private static int _lastStockNumber = 10000;

    // Convert to properties and private setters force subclasses to use the Ctor
    public decimal CostPrice { get; private set; }
    public string Description { get; private set; }
    public int StockNumber { get; private set; }

    // Static is now read only
    public static int LastStockNumber
    {
        get { return _lastStockNumber; }
    }

    // Constructor not allowing for setting of Stock Number
    public StockItem(string description, decimal costPrice)
    {
        Interlocked.Increment(ref _lastStockNumber);
        this.CostPrice = costPrice;
        this.Description = description;
    }

    // Constructor allowing for direct setting of stockNumber
    public StockItem(int stockNumber, string description, decimal costPrice)
    {
        this.StockNumber = stockNumber;
        this.CostPrice = costPrice;
        this.Description = description;
    }
}

上記は、サブクラスが上記のコンストラクターの 1 つを使用して基本クラスのプロパティを設定し、該当する場合は、より制御されたスレッド セーフな方法で静的から StockNumber を自動割り当てするように強制します。

最後に、基本クラスは、明示的な getter メソッドの代わりに auto プロパティを使用することもできます。

public float GetWeight()
{
    return Weight;
}

public Weight {get; private set;}
于 2015-01-06T05:03:02.910 に答える