- Timestamp:
- 04/03/09 15:09:06 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Persistence/Default/Decomposers/X2StringDecomposer.cs
r1494 r1514 6 6 using System.Globalization; 7 7 using System.Text; 8 using System.Collections;9 8 10 9 namespace HeuristicLab.Persistence.Default.Decomposers { … … 28 27 }; 29 28 30 private static readonly Dictionary<Type, MethodInfo> numberParser ;29 private static readonly Dictionary<Type, MethodInfo> numberParsers; 31 30 32 31 static Number2StringDecomposer() { 33 numberParser = new Dictionary<Type, MethodInfo>();32 numberParsers = new Dictionary<Type, MethodInfo>(); 34 33 foreach ( var type in numberTypes ) { 35 numberParser [type] = type34 numberParsers[type] = type 36 35 .GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, 37 36 null, new[] {typeof (string)}, null); … … 40 39 41 40 public bool CanDecompose(Type type) { 42 return numberParser .ContainsKey(type);43 } 44 45 public string SimpleDecompose(object obj) {41 return numberParsers.ContainsKey(type); 42 } 43 44 public string Format(object obj) { 46 45 if (obj.GetType() == typeof(float)) 47 46 return ((float)obj).ToString("r", CultureInfo.InvariantCulture); 48 elseif (obj.GetType() == typeof(double))47 if (obj.GetType() == typeof(double)) 49 48 return ((double)obj).ToString("r", CultureInfo.InvariantCulture); 50 elseif (obj.GetType() == typeof(decimal))49 if (obj.GetType() == typeof(decimal)) 51 50 return ((decimal)obj).ToString("r", CultureInfo.InvariantCulture); 52 else 53 return obj.ToString(); 51 return obj.ToString(); 54 52 } 55 53 56 54 public IEnumerable<Tag> DeCompose(object obj) { 57 yield return new Tag( SimpleDecompose(obj));55 yield return new Tag(Format(obj)); 58 56 } 59 57 … … 63 61 64 62 public object Parse(string stringValue, Type type) { 65 return numberParser [type]63 return numberParsers[type] 66 64 .Invoke(null, 67 65 BindingFlags.Static | BindingFlags.PutRefDispProperty, … … 120 118 sb.Append(a.GetLowerBound(i)).Append(';'); 121 119 foreach (var number in a) { 122 sb.Append(numberDecomposer. SimpleDecompose(number)).Append(';');120 sb.Append(numberDecomposer.Format(number)).Append(';'); 123 121 } 124 122 yield return new Tag("compact array", sb.ToString()); … … 130 128 131 129 public object Populate(object instance, IEnumerable<Tag> tags, Type type) { 132 var iter = tags.GetEnumerator(); 133 iter.MoveNext(); 134 var it = ((string) iter.Current.Value).Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries).GetEnumerator(); 135 it.MoveNext(); 136 int rank = int.Parse((string) it.Current); 137 it.MoveNext(); 130 var tagIter = tags.GetEnumerator(); 131 tagIter.MoveNext(); 132 var valueIter = ((string) tagIter.Current.Value) 133 .Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries) 134 .GetEnumerator(); 135 valueIter.MoveNext(); 136 int rank = int.Parse((string) valueIter.Current); 138 137 int[] lengths = new int[rank]; 139 int[] lowerBounds = new int[rank]; 140 for (int i = 0; i < rank; i++, it.MoveNext()) 141 lengths[i] = int.Parse((string) it.Current); 142 for (int i = 0; i < rank; i++, it.MoveNext()) 143 lowerBounds[i] = int.Parse((string)it.Current); 144 Array a = Array.CreateInstance(type.GetElementType(), lengths, lowerBounds); 138 int[] lowerBounds = new int[rank]; 139 for (int i = 0; i < rank; i++) { 140 valueIter.MoveNext(); 141 lengths[i] = int.Parse((string) valueIter.Current); 142 } 143 for (int i = 0; i < rank; i++) { 144 valueIter.MoveNext(); 145 lowerBounds[i] = int.Parse((string) valueIter.Current); 146 } 147 Type elementType = type.GetElementType(); 148 Array a = Array.CreateInstance(elementType, lengths, lowerBounds); 145 149 int[] positions = (int[]) lowerBounds.Clone(); 146 while ( it.MoveNext()) {150 while (valueIter.MoveNext()) { 147 151 a.SetValue( 148 numberDecomposer.Parse((string) it.Current, type.GetElementType()),152 numberDecomposer.Parse((string)valueIter.Current, elementType), 149 153 positions); 150 154 positions[0] += 1; … … 167 171 new Number2StringDecomposer(); 168 172 173 private static readonly Dictionary<Type, Type> interfaceCache = new Dictionary<Type, Type>(); 174 175 public Type GetGenericEnumerableInterface(Type type) { 176 if (interfaceCache.ContainsKey(type)) 177 return interfaceCache[type]; 178 foreach (Type iface in type.GetInterfaces()) { 179 if (iface.IsGenericType && 180 iface.GetGenericTypeDefinition() == typeof(IEnumerable<>) && 181 numberDecomposer.CanDecompose(iface.GetGenericArguments()[0])) { 182 interfaceCache.Add(type, iface); 183 return iface; 184 } 185 } 186 interfaceCache.Add(type, null); 187 return null; 188 } 189 169 190 public bool ImplementsGenericEnumerable(Type type) { 170 foreach( Type iface in type.GetInterfaces() ) { 171 if ( iface.IsGenericType && 172 iface.GetGenericTypeDefinition() == typeof(IEnumerable<>) && 173 numberDecomposer.CanDecompose(iface.GetGenericArguments()[0]) ) 174 return true; 175 } 176 return false; 191 return GetGenericEnumerableInterface(type) != null; 177 192 } 178 193 … … 195 210 196 211 public IEnumerable<Tag> DeCompose(object obj) { 197 Type elementType = obj.GetType().GetGenericArguments()[0]; 198 Type instantiatedGenericInterface = 199 typeof (IEnumerable<>).MakeGenericType(new[] {elementType}); 200 MethodInfo genericGetEnumeratorMethod = 201 instantiatedGenericInterface.GetMethod("GetEnumerator"); 202 InterfaceMapping iMap = obj.GetType().GetInterfaceMap(instantiatedGenericInterface); 212 Type type = obj.GetType(); 213 Type enumerable = GetGenericEnumerableInterface(type); 214 InterfaceMapping iMap = obj.GetType().GetInterfaceMap(enumerable); 203 215 MethodInfo getEnumeratorMethod = 204 iMap.TargetMethods[Array.IndexOf(iMap.InterfaceMethods, genericGetEnumeratorMethod)]; 216 iMap.TargetMethods[ 217 Array.IndexOf( 218 iMap.InterfaceMethods, 219 enumerable.GetMethod("GetEnumerator"))]; 205 220 object[] empty = new object[] {}; 206 221 object genericEnumerator = getEnumeratorMethod.Invoke(obj, empty); … … 210 225 while ( (bool)moveNextMethod.Invoke(genericEnumerator, empty) ) 211 226 sb.Append( 212 numberDecomposer. SimpleDecompose(227 numberDecomposer.Format( 213 228 currentProperty.GetValue(genericEnumerator, null))).Append(';'); 214 229 yield return new Tag("compact enumerable", sb.ToString()); … … 220 235 221 236 public object Populate(object instance, IEnumerable<Tag> tags, Type type) { 222 Type elementType = type.GetGenericArguments()[0]; 237 Type enumerable = GetGenericEnumerableInterface(type); 238 Type elementType = enumerable.GetGenericArguments()[0]; 223 239 MethodInfo addMethod = type.GetMethod("Add"); 224 240 var tagEnumerator = tags.GetEnumerator();
Note: See TracChangeset
for help on using the changeset viewer.