Changeset 6380 for trunk/sources
- Timestamp:
- 06/07/11 16:55:38 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Common/3.3/ObjectExtensions.cs
r6205 r6380 24 24 using System.Collections.Generic; 25 25 using System.Collections.Specialized; 26 using System.Linq; 26 27 using System.Reflection; 27 using System.Threading;28 28 29 29 namespace HeuristicLab.Common { 30 30 public static class ObjectExtensions { 31 31 public static IEnumerable<object> GetObjectGraphObjects(this object obj) { 32 if (obj == null) return Enumerable.Empty<object>(); 33 32 34 var objects = new HashSet<object>(); 33 obj.CollectObjectGraphObjects(objects); 35 var stack = new Stack<object>(); 36 37 stack.Push(obj); 38 while (stack.Count > 0) { 39 object current = stack.Pop(); 40 Type type = obj.GetType(); 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(Dictionary<,>)) || 74 type.IsSubclassOfRawGeneric(typeof(SortedDictionary<,>)) || 75 type.IsSubclassOfRawGeneric(typeof(SortedList<,>)) || 76 obj is SortedList || 77 obj is OrderedDictionary || 78 obj is ListDictionary || 79 obj is Hashtable) { 65 80 var dictionary = obj as IDictionary; 66 81 foreach (object value in dictionary.Keys) 67 CollectObjectGraphObjects(value, objects);82 yield return value; 68 83 foreach (object value in dictionary.Values) 69 CollectObjectGraphObjects(value, objects); 70 return; 84 yield return value; 71 85 } else if (type.IsArray || type.IsSubclassOfRawGeneric(typeof(HashSet<>))) { 72 86 var enumerable = obj as IEnumerable; 73 87 foreach (var value in enumerable) 74 CollectObjectGraphObjects(value, objects); 75 return; 88 yield return value; 89 } else { 90 foreach (FieldInfo f in type.GetAllFields()) { 91 yield return f.GetValue(obj); 92 } 76 93 } 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 94 } 90 95 }
Note: See TracChangeset
for help on using the changeset viewer.