1 using System;
2 using System.Runtime.InteropServices;
3 
4 namespace Martin.Collections.Generic {
5 	[Serializable]
6 	public abstract class EqualityComparer <T> : IEqualityComparer <T> {
7 
EqualityComparer()8 		static EqualityComparer ()
9 		{
10 			if (typeof (IEquatable <T>).IsAssignableFrom (typeof (T)))
11 				_default = (EqualityComparer <T>) Activator.CreateInstance (typeof (IEquatableOfTEqualityComparer<>).MakeGenericType (typeof (T)));
12 			else
13 				_default = new DefaultComparer ();
14 		}
15 
16 
GetHashCode(T obj)17 		public abstract int GetHashCode (T obj);
Equals(T x, T y)18 		public abstract bool Equals (T x, T y);
19 
20 		static readonly EqualityComparer <T> _default;
21 
22 		public static EqualityComparer <T> Default {
23 			get {
24 				return _default;
25 			}
26 		}
27 
28 		[Serializable]
29 		class DefaultComparer : EqualityComparer<T> {
30 
GetHashCode(T obj)31 			public override int GetHashCode (T obj)
32 			{
33 				return obj.GetHashCode ();
34 			}
35 
Equals(T x, T y)36 			public override bool Equals (T x, T y)
37 			{
38 				if (x == null)
39 					return y == null;
40 
41 				return x.Equals (y);
42 			}
43 		}
44 	}
45 
46 	[Serializable]
47 	class IEquatableOfTEqualityComparer <T> : EqualityComparer <T> where T : IEquatable <T> {
48 
GetHashCode(T obj)49 		public override int GetHashCode (T obj)
50 		{
51 			return obj.GetHashCode ();
52 		}
53 
Equals(T x, T y)54 		public override bool Equals (T x, T y)
55 		{
56 			if (x == null)
57 				return y == null;
58 
59 			return x.Equals (y);
60 		}
61 	}
62 
63 	public interface IEqualityComparer<T> {
Equals(T x, T y)64 		bool Equals (T x, T y);
GetHashCode(T obj)65 		int GetHashCode (T obj);
66 	}
67 
68 	class X
69 	{
Main()70 		public static void Main ()
71 		{ }
72 	}
73 }
74