| | | 1 | | // |
| | | 2 | | // Copyright 2010 Ekon Benefits |
| | | 3 | | // |
| | | 4 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
| | | 5 | | // you may not use this file except in compliance with the License. |
| | | 6 | | // You may obtain a copy of the License at |
| | | 7 | | // |
| | | 8 | | // http://www.apache.org/licenses/LICENSE-2.0 |
| | | 9 | | // |
| | | 10 | | // Unless required by applicable law or agreed to in writing, software |
| | | 11 | | // distributed under the License is distributed on an "AS IS" BASIS, |
| | | 12 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| | | 13 | | // See the License for the specific language governing permissions and |
| | | 14 | | // limitations under the License. |
| | | 15 | | |
| | | 16 | | using System; |
| | | 17 | | using System.Collections.Generic; |
| | | 18 | | using System.Linq; |
| | | 19 | | using System.Reflection; |
| | | 20 | | using System.Text; |
| | | 21 | | |
| | | 22 | | namespace ImpromptuInterface.Build |
| | | 23 | | { |
| | | 24 | | /// <summary> |
| | | 25 | | /// Type that Encompasses Hashing a group of Types in various ways |
| | | 26 | | /// </summary> |
| | | 27 | | public class TypeHash |
| | | 28 | | { |
| | | 29 | | /// <summary> |
| | | 30 | | /// Equalses the specified other. |
| | | 31 | | /// </summary> |
| | | 32 | | /// <param name="other">The other.</param> |
| | | 33 | | /// <returns></returns> |
| | | 34 | | public bool Equals(TypeHash other) |
| | | 35 | | { |
| | 1122 | 36 | | if (ReferenceEquals(null, other)) return false; |
| | 1120 | 37 | | if (ReferenceEquals(this, other)) return true; |
| | | 38 | | |
| | 1120 | 39 | | if (InformalInterface != null || other.InformalInterface !=null) |
| | | 40 | | { |
| | 3 | 41 | | if (InformalInterface == null || other.InformalInterface == null) |
| | 1 | 42 | | return false; |
| | | 43 | | |
| | 2 | 44 | | if (Types.Length != other.Types.Length) |
| | 0 | 45 | | return false; |
| | | 46 | | |
| | 2 | 47 | | var tTypes = Types.SequenceEqual(other.Types); |
| | | 48 | | |
| | 2 | 49 | | if (!tTypes ) |
| | 0 | 50 | | return false; |
| | | 51 | | |
| | 2 | 52 | | return InformalInterface.SequenceEqual(other.InformalInterface); |
| | | 53 | | } |
| | | 54 | | |
| | | 55 | | |
| | 1117 | 56 | | return Types.SequenceEqual(other.Types); |
| | | 57 | | } |
| | | 58 | | |
| | | 59 | | /// <summary> |
| | | 60 | | /// Determines whether the specified <see cref="System.Object"/> is equal to this instance. |
| | | 61 | | /// </summary> |
| | | 62 | | /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param> |
| | | 63 | | /// <returns> |
| | | 64 | | /// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c |
| | | 65 | | /// </returns> |
| | | 66 | | public override bool Equals(object obj) |
| | | 67 | | { |
| | 1194 | 68 | | if (ReferenceEquals(null, obj)) return false; |
| | 1267 | 69 | | if (ReferenceEquals(this, obj)) return true; |
| | 1122 | 70 | | if (obj.GetType() != typeof(TypeHash)) return false; |
| | 1120 | 71 | | return Equals((TypeHash)obj); |
| | | 72 | | } |
| | | 73 | | |
| | | 74 | | /// <summary> |
| | | 75 | | /// Returns a hash code for this instance. |
| | | 76 | | /// </summary> |
| | | 77 | | /// <returns> |
| | | 78 | | /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. |
| | | 79 | | /// </returns> |
| | | 80 | | public override int GetHashCode() |
| | | 81 | | { |
| | | 82 | | unchecked |
| | | 83 | | { |
| | | 84 | | |
| | 2152 | 85 | | if (Types.Length > 16) |
| | | 86 | | { |
| | 0 | 87 | | return Types.Length.GetHashCode(); |
| | | 88 | | } |
| | | 89 | | |
| | | 90 | | |
| | 2152 | 91 | | var tReturn = Types.Aggregate(1, (current, type) => (current * 397) ^ type.GetHashCode()); |
| | | 92 | | |
| | 2152 | 93 | | if (InformalInterface != null) |
| | | 94 | | { |
| | 6 | 95 | | tReturn = InformalInterface.Aggregate(tReturn, (current, type) => (current * 397) ^ type.GetHashCode |
| | | 96 | | } |
| | 2152 | 97 | | return tReturn; |
| | | 98 | | } |
| | | 99 | | } |
| | | 100 | | |
| | | 101 | | /// <summary> |
| | | 102 | | /// Implements the operator ==. |
| | | 103 | | /// </summary> |
| | | 104 | | /// <param name="left">The left.</param> |
| | | 105 | | /// <param name="right">The right.</param> |
| | | 106 | | /// <returns>The result of the operator.</returns> |
| | | 107 | | public static bool operator ==(TypeHash left, TypeHash right) |
| | | 108 | | { |
| | 1 | 109 | | return Equals(left, right); |
| | | 110 | | } |
| | | 111 | | |
| | | 112 | | /// <summary> |
| | | 113 | | /// Implements the operator !=. |
| | | 114 | | /// </summary> |
| | | 115 | | /// <param name="left">The left.</param> |
| | | 116 | | /// <param name="right">The right.</param> |
| | | 117 | | /// <returns>The result of the operator.</returns> |
| | | 118 | | public static bool operator !=(TypeHash left, TypeHash right) |
| | | 119 | | { |
| | 2 | 120 | | return !Equals(left, right); |
| | | 121 | | } |
| | | 122 | | |
| | | 123 | | /// <summary> |
| | | 124 | | /// Types to be hashed |
| | | 125 | | /// </summary> |
| | | 126 | | public readonly MemberInfo[] Types; |
| | | 127 | | |
| | | 128 | | /// <summary> |
| | | 129 | | /// The Informal Interface to be hashed |
| | | 130 | | /// </summary> |
| | | 131 | | public readonly IDictionary<string,Type> InformalInterface; |
| | | 132 | | |
| | | 133 | | /// <summary> |
| | | 134 | | /// Initializes a new instance of the <see cref="TypeHash"/> class. |
| | | 135 | | /// </summary> |
| | | 136 | | /// <param name="moreTypes">The more types.</param> |
| | | 137 | | [Obsolete("Use TypeHash.Create instead.")] |
| | | 138 | | public TypeHash(IEnumerable<Type> moreTypes) |
| | 6 | 139 | | :this(false,moreTypes.ToArray()) |
| | | 140 | | { |
| | | 141 | | |
| | 6 | 142 | | } |
| | | 143 | | |
| | 1549 | 144 | | private TypeHash() |
| | | 145 | | { |
| | | 146 | | |
| | 1549 | 147 | | } |
| | | 148 | | |
| | | 149 | | /// <summary> |
| | | 150 | | /// Initializes a new instance of the <see cref="TypeHash"/> class. |
| | | 151 | | /// For use when you have must distinguish one type; and the rest aren't strict |
| | | 152 | | /// </summary> |
| | | 153 | | /// <param name="type1">The type1.</param> |
| | | 154 | | /// <param name="moreTypes">The more types.</param> |
| | | 155 | | [Obsolete("Use TypeHash.Create instead.")] |
| | | 156 | | public TypeHash(Type type1, params Type[] moreTypes) |
| | 127 | 157 | | :this() |
| | | 158 | | { |
| | 127 | 159 | | Types = new[] { type1 }.Concat(moreTypes.OrderBy(it => it.Name)).ToArray(); |
| | 127 | 160 | | InformalInterface = null; |
| | 127 | 161 | | } |
| | | 162 | | |
| | | 163 | | |
| | | 164 | | |
| | | 165 | | /// <summary> |
| | | 166 | | /// Initializes a new instance of the <see cref="TypeHash"/> class. |
| | | 167 | | /// </summary> |
| | | 168 | | /// <param name="type1">The type1.</param> |
| | | 169 | | /// <param name="informalInterface">The informal interface.</param> |
| | | 170 | | [Obsolete("Use TypeHash.Create instead.")] |
| | | 171 | | public TypeHash(Type type1, IDictionary<string, Type> informalInterface) |
| | 5 | 172 | | : this() |
| | | 173 | | { |
| | 5 | 174 | | Types = new[] {type1}; |
| | 5 | 175 | | InformalInterface = informalInterface; |
| | 5 | 176 | | } |
| | | 177 | | |
| | | 178 | | /// <summary> |
| | | 179 | | /// Initializes a new instance of the <see cref="TypeHash"/> class. |
| | | 180 | | /// </summary> |
| | | 181 | | /// <param name="strictOrder">if set to <c>true</c> [strict order].</param> |
| | | 182 | | /// <param name="moreTypes">types.</param> |
| | | 183 | | [Obsolete("Use TypeHash.Create instead.")] |
| | 1417 | 184 | | public TypeHash(bool strictOrder, params MemberInfo[] moreTypes):this() |
| | | 185 | | { |
| | 1417 | 186 | | Types = strictOrder |
| | 1417 | 187 | | ? moreTypes |
| | 1417 | 188 | | : moreTypes.OrderBy(it => it.Name).ToArray(); |
| | 1417 | 189 | | } |
| | | 190 | | |
| | | 191 | | /// <summary> |
| | | 192 | | /// Creates the TypeHash |
| | | 193 | | /// </summary> |
| | | 194 | | /// <param name="moreTypes">The more types.</param> |
| | | 195 | | /// <returns></returns> |
| | | 196 | | public static TypeHash Create(IEnumerable<Type> moreTypes) |
| | | 197 | | { |
| | | 198 | | #pragma warning disable 612,618 |
| | 6 | 199 | | return new TypeHash(moreTypes); |
| | | 200 | | #pragma warning restore 612,618 |
| | | 201 | | } |
| | | 202 | | /// <summary> |
| | | 203 | | /// Creates the TypeHash |
| | | 204 | | /// </summary> |
| | | 205 | | /// <param name="type1">The type1.</param> |
| | | 206 | | /// <param name="moreTypes">The more types.</param> |
| | | 207 | | /// <returns></returns> |
| | | 208 | | public static TypeHash Create(Type type1, params Type[] moreTypes) |
| | | 209 | | { |
| | | 210 | | #pragma warning disable 612,618 |
| | 127 | 211 | | return new TypeHash(type1, moreTypes); |
| | | 212 | | #pragma warning restore 612,618 |
| | | 213 | | } |
| | | 214 | | /// <summary> |
| | | 215 | | /// Creates the TypeHash |
| | | 216 | | /// </summary> |
| | | 217 | | /// <param name="type1">The type1.</param> |
| | | 218 | | /// <param name="informalInterface">The informal interface.</param> |
| | | 219 | | /// <returns></returns> |
| | | 220 | | public static TypeHash Create(Type type1, IDictionary<string, Type> informalInterface) |
| | | 221 | | { |
| | | 222 | | #pragma warning disable 612,618 |
| | 5 | 223 | | return new TypeHash(type1, informalInterface); |
| | | 224 | | #pragma warning restore 612,618 |
| | | 225 | | } |
| | | 226 | | /// <summary> |
| | | 227 | | /// Creates the TypeHash |
| | | 228 | | /// </summary> |
| | | 229 | | /// <param name="strictOrder">if set to <c>true</c> [strict order].</param> |
| | | 230 | | /// <param name="moreTypes">The more types.</param> |
| | | 231 | | /// <returns></returns> |
| | | 232 | | public static TypeHash Create(bool strictOrder, params MemberInfo[] moreTypes) |
| | | 233 | | { |
| | | 234 | | #pragma warning disable 612,618 |
| | 1411 | 235 | | return new TypeHash(strictOrder, moreTypes); |
| | | 236 | | #pragma warning restore 612,618 |
| | | 237 | | } |
| | | 238 | | } |
| | | 239 | | } |