comparison Source/Common/CompoundValue.cs @ 0:f990fcb411a9

Копия текущей версии из github
author cin
date Thu, 27 Mar 2014 21:46:09 +0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f990fcb411a9
1 using System;
2 using System.Collections;
3
4 namespace BLToolkit.Common
5 {
6 public class CompoundValue : IComparable, IEquatable<CompoundValue>
7 {
8 public CompoundValue(params object[] values)
9 {
10 if (values == null)
11 throw new ArgumentNullException("values");
12
13 // Note that the compound hash is precalculated.
14 // This means that CompoundValue can be used only with immutable values.
15 // Otherwise the behaviour is undefined.
16 //
17 _hash = CalcHashCode(values);
18 _values = values;
19 }
20
21 private readonly object[] _values;
22 private readonly int _hash;
23
24 public int Count
25 {
26 get { return _values == null ? 0 : _values.Length; }
27 }
28
29 public object this[int index]
30 {
31 get { return _values == null ? null : _values[index]; }
32 }
33
34 private static int CalcHashCode(object[] values)
35 {
36 if (values.Length == 0)
37 return 0;
38
39 object o = values[0];
40 int hash = o == null ? 0 : o.GetHashCode();
41
42 for (int i = 1; i < values.Length; i++)
43 {
44 o = values[i];
45 hash = ((hash << 5) + hash) ^ (o == null ? 0 : o.GetHashCode());
46 }
47
48 return hash;
49 }
50
51 #region IComparable Members
52
53 public int CompareTo(object obj)
54 {
55 var objValues = ((CompoundValue)obj)._values;
56
57 if (_values.Length != objValues.Length)
58 return _values.Length - objValues.Length;
59
60 for (var i = 0; i < _values.Length; i++)
61 {
62 var n = Comparer.Default.Compare(_values[i], objValues[i]);
63
64 if (n != 0)
65 return n;
66 }
67
68 return 0;
69 }
70
71 #endregion
72
73 #region Object Overrides
74
75 public override int GetHashCode()
76 {
77 return _hash;
78 }
79
80 public override bool Equals(object obj)
81 {
82 if (!(obj is CompoundValue))
83 return false;
84
85 return Equals((CompoundValue)obj);
86 }
87
88 #endregion
89
90 #region IEquatable<CompoundValue> Members
91
92 public bool Equals(CompoundValue other)
93 {
94 if (_hash != other._hash)
95 return false;
96
97 object[] values = other._values;
98
99 if (_values.Length != values.Length)
100 return false;
101
102 for (int i = 0; i < _values.Length; i++)
103 {
104 object x = _values[i];
105 object y = values[i];
106
107 if (x == null && y == null)
108 continue;
109
110 if (x == null || y == null)
111 return false;
112
113 if (x.Equals(y) == false)
114 return false;
115 }
116
117 return true;
118 }
119
120 #endregion
121 }
122 }