Результат не дает ожидаемого результата
Это мой код:
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, я получаю согласно вышеуказанному. Не могу понять, почему?
2 ответа
Ваш конструктор для StockItem
который принимает определенный StockNumber, вызывает другой конструктор, который увеличивает LastStockNumber
, Поэтому каждый раз, когда вы создаете экземпляр StockItem
(или что-то, что происходит от StockItem
), LastStockNumber
будет увеличиваться, даже если номер запаса был указан в конструкторе.
На самом деле, вы увеличиваете LastStockNumber
во многих из конструкторов, что привело бы к тому, что он был увеличен как минимум вдвое при создании некоторых типов объектов.
Редактировать:
Что касается того, как это исправить, я бы начал с изменения StockItem
конструктор, который использует LastStockNumber, так что вместо вызова другого конструктора он просто устанавливает цену и само описание:
public StockItem(int StockNumber, string Description, float CostPrice)
{
this.StockNumber = StockNumber;
this.CostPrice = CostPrice;
this.Description = Description;
}
Тогда я бы удалил везде, что вы увеличиваете LastStockNumber
в конструкторах производных классов.
Вы также должны сделать LastStockNumber
частный. После внесения этих изменений, если вы продолжите создавать объекты такими, какие вы есть, LastStockNumber
никогда не будет увеличен, потому что вы всегда указываете номер запаса при создании объекта.
Конструктор 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 напрямую.
Точно так же Trolley создается напрямую с использованием того же конструктора 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;
}
}
Вышеприведенное заставит подклассы использовать один из описанных выше конструкторов для установки свойств базового класса и, если применимо, для автоматического присвоения StockNumber из статического объекта в более управляемом и безопасном для потока виде.
Наконец, базовые классы также могут использовать автоматические свойства вместо явных методов получения, то есть замены
public float GetWeight()
{
return Weight;
}
с
public Weight {get; private set;}