main
 1using System.Linq;
 2
 3namespace jive
 4{
 5  public class ValueType<T>
 6  {
 7    public override bool Equals(object obj)
 8    {
 9      if (ReferenceEquals(null, obj)) return false;
10      if (ReferenceEquals(this, obj)) return true;
11      if (!(obj is ValueType<T>)) return false;
12      return Equals((ValueType<T>) obj);
13    }
14
15    public bool Equals(ValueType<T> other)
16    {
17      if (ReferenceEquals(null, other)) return false;
18      if (ReferenceEquals(this, other)) return true;
19      return PropertiesMatch(other);
20    }
21
22    bool PropertiesMatch(ValueType<T> other)
23    {
24      return !GetType().GetProperties().Any(x =>
25          {
26          var thisValue = x.GetValue(this, null);
27          var otherValue = x.GetValue(other, null);
28          return !thisValue.Equals(otherValue);
29          });
30    }
31
32    public override int GetHashCode()
33    {
34      return GetType().GetProperties().Aggregate(0, (prev, prop) => (prev*397) ^ prop.GetHashCode());
35    }
36  }
37}