using System.Collections.Generic;
using System.Collections.ObjectModel;
public readonly int PartNumber;
public readonly string Description;
public readonly double UnitPrice;
private int _quantity = 0;
public OrderItem(int partNumber, string description, int quantity, double unitPrice)
this.PartNumber = partNumber;
this.Description = description;
this.Quantity = quantity;
this.UnitPrice = unitPrice;
throw new ArgumentException("Quantity cannot be negative.");
public override string ToString()
return String.Format("{0,9} {1,6} {2,-12} at {3,8:#,###.00} = {4,10:###,###.00}",
PartNumber, _quantity, Description, UnitPrice, UnitPrice * _quantity);
private OrderItemCollection _orderItems;
public OrderItemReadOnlyCollection OrderItems
return new OrderItemReadOnlyCollection(_orderItems);
_orderItems = new OrderItemCollection();
_orderItems.OrderItemAdded += OrderItemAdded;
_orderItems.OrderItemRemoved += OrderItemRemoved;
public Order(IEnumerable<OrderItem> orderItems):this()
public void AddOrderItem(OrderItem orderItem)
throw new ArgumentNullException(String.Format("{0} can't be null", orderItem));
_orderItems.AddItem(orderItem);
public void RemoveOrderItem(OrderItem orderItem)
throw new ArgumentNullException(String.Format("{0} can't be null", orderItem));
_orderItems.RemoveItem(orderItem);
public void AddRange(IEnumerable<OrderItem> orderItems)
throw new ArgumentNullException(String.Format("{0} can't be null", orderItems));
foreach (OrderItem item in orderItems)
_orderItems.AddItem(item);
private void OrderItemAdded(object sender, OrderItemCollectionEventArgs eventArgs)
Console.WriteLine(String.Format("Order item with number {0} was added", eventArgs.OrderItem.PartNumber));
private void OrderItemRemoved(object sender, OrderItemCollectionEventArgs eventArgs)
Console.WriteLine(String.Format("Order item with number {0} was removed", eventArgs.OrderItem.PartNumber));
public class OrderItemCollection: Collection<OrderItem>
public event EventHandler<OrderItemCollectionEventArgs> OrderItemAdded = delegate {};
public event EventHandler<OrderItemCollectionEventArgs> OrderItemRemoved = delegate {};
public void AddItem(OrderItem orderItem)
public void RemoveItem(OrderItem orderItem)
protected virtual void OnAddingOrderItem(OrderItemCollectionEventArgs eventArgs)
this.OrderItemAdded.Invoke(this, eventArgs);
protected virtual void OnRemovingOrderItem(OrderItemCollectionEventArgs eventArgs)
this.OrderItemRemoved.Invoke(this, eventArgs);
public class OrderItemReadOnlyCollection: ReadOnlyCollection<OrderItem>
public OrderItemReadOnlyCollection(IList<OrderItem> orderItems) :base(orderItems)
public class OrderItemCollectionEventArgs: EventArgs
private OrderItem _orderItem;
public OrderItem OrderItem
public OrderItemCollectionEventArgs(OrderItem orderItem)
this._orderItem = orderItem;
public static void Main()
var orderItems = new OrderItem[]
new OrderItem(110072674, "Widget", 400, 45.17),
new OrderItem(110072675, "Sprocket", 27, 5.3),
new OrderItem(101030411, "Motor", 10, 237.5),
new OrderItem(110072684, "Gear", 175, 5.17)
var order = new Order(orderItems);
Display("Order #1", order);
private static void Display(string title, Order order)
Console.WriteLine(title);
foreach (OrderItem item in order.OrderItems)