- Timestamp:
- 09/14/11 13:59:25 (13 years ago)
- Location:
- branches/PersistenceSpeedUp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/PersistenceSpeedUp
- Property svn:ignore
-
old new 12 12 *.psess 13 13 *.vsp 14 *.docstates
-
- Property svn:mergeinfo changed
- Property svn:ignore
-
branches/PersistenceSpeedUp/HeuristicLab.Common/3.3/ObjectExtensions.cs
r6205 r6760 24 24 using System.Collections.Generic; 25 25 using System.Collections.Specialized; 26 using System.Linq; 26 27 using System.Reflection; 27 28 using System.Threading; … … 30 31 public static class ObjectExtensions { 31 32 public static IEnumerable<object> GetObjectGraphObjects(this object obj) { 33 if (obj == null) return Enumerable.Empty<object>(); 34 32 35 var objects = new HashSet<object>(); 33 obj.CollectObjectGraphObjects(objects); 36 var stack = new Stack<object>(); 37 38 stack.Push(obj); 39 while (stack.Count > 0) { 40 object current = stack.Pop(); 41 objects.Add(current); 42 43 foreach (object o in GetChildObjects(current)) { 44 if (o != null && !objects.Contains(o) && !ExcludeType(o.GetType())) 45 stack.Push(o); 46 } 47 } 48 34 49 return objects; 35 50 } … … 45 60 /// compared to traverse their internal data structures. 46 61 /// </summary> 47 private static void CollectObjectGraphObjects(this object obj, HashSet<object> objects) { 48 if (obj == null || objects.Contains(obj)) return; 62 private static bool ExcludeType(Type type) { 63 return type.IsPrimitive || 64 type == typeof(string) || 65 type == typeof(decimal) || 66 typeof(Delegate).IsAssignableFrom(type) || 67 typeof(Pointer).IsAssignableFrom(type) || 68 (type.HasElementType && ExcludeType(type.GetElementType())); 69 } 70 private static IEnumerable<object> GetChildObjects(object obj) { 49 71 Type type = obj.GetType(); 50 if (ExcludeType(type)) return;51 if (type.HasElementType && ExcludeType(type.GetElementType())) return;52 72 53 objects.Add(obj); 54 55 if (type.IsSubclassOfRawGeneric(typeof(ThreadLocal<>))) return; // avoid stack overflow when the field `ConcurrentStack<int> s_availableIndices` too grows large 56 57 // performance critical to handle dictionaries, hashsets and hashtables in a special way 58 if (type.IsSubclassOfRawGeneric(typeof(Dictionary<,>)) || 59 type.IsSubclassOfRawGeneric(typeof(SortedDictionary<,>)) || 60 type.IsSubclassOfRawGeneric(typeof(SortedList<,>)) || 61 obj is SortedList || 62 obj is OrderedDictionary || 63 obj is ListDictionary || 64 obj is Hashtable) { 73 if (type.IsSubclassOfRawGeneric(typeof(ThreadLocal<>))) { 74 PropertyInfo info = type.GetProperty("Value"); 75 object value = info.GetValue(obj, null); 76 if (value != null) yield return value; 77 } else if (type.IsSubclassOfRawGeneric(typeof(Dictionary<,>)) || 78 type.IsSubclassOfRawGeneric(typeof(SortedDictionary<,>)) || 79 type.IsSubclassOfRawGeneric(typeof(SortedList<,>)) || 80 obj is SortedList || 81 obj is OrderedDictionary || 82 obj is ListDictionary || 83 obj is Hashtable) { 65 84 var dictionary = obj as IDictionary; 66 85 foreach (object value in dictionary.Keys) 67 CollectObjectGraphObjects(value, objects);86 yield return value; 68 87 foreach (object value in dictionary.Values) 69 CollectObjectGraphObjects(value, objects); 70 return; 88 yield return value; 71 89 } else if (type.IsArray || type.IsSubclassOfRawGeneric(typeof(HashSet<>))) { 72 90 var enumerable = obj as IEnumerable; 73 91 foreach (var value in enumerable) 74 CollectObjectGraphObjects(value, objects); 75 return; 92 yield return value; 93 } else { 94 foreach (FieldInfo f in type.GetAllFields()) { 95 yield return f.GetValue(obj); 96 } 76 97 } 77 78 foreach (FieldInfo f in type.GetAllFields()) {79 f.GetValue(obj).CollectObjectGraphObjects(objects);80 }81 }82 83 private static bool ExcludeType(Type type) {84 return type.IsPrimitive ||85 type == typeof(string) ||86 type == typeof(decimal) ||87 typeof(Delegate).IsAssignableFrom(type) ||88 typeof(Pointer).IsAssignableFrom(type);89 98 } 90 99 }
Note: See TracChangeset
for help on using the changeset viewer.