I have a generic collection which is representative of an order with each line item being an "Item" class object. The order's total value is based off of the combined values of all the line items. I currently have a way of getting the total value on an order whenever the "TotalValue" property is retrieved, but I find this method somewhat inelegant because it feels like Schrodinger's variable; it only becomes the total value when observed.
Is there any way that I can get an "Item" member held inside a "Quote" collection to trigger the "updateValue" method of the instance of the Quote class containing it whenever the "Item" object goes to modify its own cost values? The item class automatically modifies its own "TotalCost" but I want it to kick it up the chain and modify the order's total cost/value at the same time.
I've tried to pare it down to keep only the relevant bits.
namespace Arbitrary
{
public class Order<T> : IEnumerable<T> where T : Item
{
private List<T> _lines = new List<T>();
private decimal _totalValue;
public decimal TotalValue
{
get { return updateValue(); }
}
private decimal updateValue()
{
_totalValue = 0;
foreach(T Item in _lines)
{
_totalValue += Item.TotalCost;
}
return _totalValue;
}
}
public class Item
{
private decimal _cost;
private int _quantity;
private decimal _totalCost;
public decimal Cost
{
get { return _cost; }
set
{
_cost = value;
_totalCost = (_cost * _quantity);
}
}
public int Quantity
{
get { return _quantity; }
set
{
_quantity = value;
_totalCost = (_cost * _quantity);
}
}
public decimal TotalCost
{
get { return _totalCost; }
}
}
}
Update: Figured it out thanks to the tip from Blorgbeard. I switched the constructor of "Item" to take the object reference of the Quote collection (since they'll never exist in absence of a Quote collection anyway). I changed the "updateValue" method to internal in order for the Item class to access it since they're both in the same assembly. The updated changes are commented with "// modified"
namespace Arbitrary
{
public class Order<T> : IEnumerable<T> where T : Item
{
private List<T> _lines = new List<T>();
private decimal _totalValue;
public decimal TotalValue
{
get { return updateValue(); }
}
internal decimal updateValue() // modified
{
_totalValue = 0;
foreach(T Item in _lines)
{
_totalValue += Item.TotalCost;
}
return _totalValue;
}
}
public class Item
{
private decimal _cost;
private int _quantity;
private decimal _totalCost;
private Quote<Item> q; // modified
public Item(Quote<Item> q) // modified
{
this.q = q; // modified
}
public decimal Cost
{
get { return _cost; }
set
{
_cost = value;
_totalCost = (_cost * _quantity);
q.updateValue(); // modified
}
}
public int Quantity
{
get { return _quantity; }
set
{
_quantity = value;
_totalCost = (_cost * _quantity);
q.updateValue(); // modified
}
}
public decimal TotalCost
{
get { return _totalCost; }
}
}
}