main
 1namespace domain
 2{
 3  public interface IQuantity
 4  {
 5    IQuantity Plus(IQuantity other);
 6    IQuantity ConvertTo(IUnitOfMeasure units);
 7    bool IsGreaterThan(IQuantity other);
 8    decimal Amount { get; }
 9    IUnitOfMeasure Units { get; }
10  }
11
12  public class Quantity : IQuantity
13  {
14    public Quantity(decimal amount, IUnitOfMeasure units)
15    {
16      Amount = amount;
17      Units = units;
18    }
19
20    public decimal Amount { get;private set; }
21
22    public IUnitOfMeasure Units { get; private set; }
23
24    public IQuantity Plus(IQuantity other)
25    {
26      if(null == other) return this;
27      return new Quantity(Amount + other.ConvertTo(Units).Amount, Units);
28    }
29
30    public IQuantity ConvertTo(IUnitOfMeasure unitOfMeasure)
31    {
32      return new Quantity(unitOfMeasure.Convert(Amount, this.Units), unitOfMeasure);
33    }
34
35    public bool IsGreaterThan(IQuantity other)
36    {
37      return this.Amount > other.ConvertTo(this.Units).Amount;
38    }
39
40    public override string ToString()
41    {
42      return string.Format("{0} {1}", Amount, Units);
43    }
44
45    public bool Equals(Quantity other)
46    {
47      if (ReferenceEquals(null, other)) return false;
48      if (ReferenceEquals(this, other)) return true;
49      return other.Amount == Amount && Equals(other.Units.GetType(), Units.GetType());
50    }
51
52    public override bool Equals(object obj)
53    {
54      if (ReferenceEquals(null, obj)) return false;
55      if (ReferenceEquals(this, obj)) return true;
56      if (obj.GetType() != typeof (Quantity)) return false;
57      return Equals((Quantity) obj);
58    }
59
60    public override int GetHashCode()
61    {
62      unchecked
63      {
64        return (Amount.GetHashCode()*397) ^ (Units != null ? Units.GetHashCode() : 0);
65      }
66    }
67  }
68}