Free cookie consent management tool by TermsFeed Policy Generator

Changeset 6192 for trunk


Ignore:
Timestamp:
05/14/11 10:40:50 (14 years ago)
Author:
cneumuel
Message:

#1522

  • included ValueTypes (which includes structs and enums)
  • avoided stack overflow by excluding Type
  • improved performance by handling dictionaries in a special way
  • avoided stack overflow by excluding ThreadLocal<> from (occured after many repetitions, when the field the field ConcurrentStack<int> s_availableIndices grew larger
  • using IsArray instead of is IEnumerable
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Common/3.3/ObjectExtensions.cs

    r6181 r6192  
    2424using System.Collections.Generic;
    2525using System.Reflection;
     26using System.Threading;
    2627
    2728namespace HeuristicLab.Common {
     
    3233      return objects;
    3334    }
    34 
     35    /// <summary>
     36    /// Types not collected:
     37    ///   * System.Delegate
     38    ///   * System.EventHandler (+ System.EventHandler<T>)
     39    ///   * Primitives (Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single)
     40    ///   * string, decimal
     41    ///   * Arrays of primitives (+ string, decimal)
     42    /// Types of which the fields are not further collected:
     43    ///   * System.Type
     44    ///   * System.Threading.ThreadLocal<T>
     45    /// </summary>
    3546    private static void CollectObjectGraphObjects(this object obj, HashSet<object> objects) {
    3647      if (obj == null || objects.Contains(obj)) return;
    37       if (obj is ValueType || obj is string) return;
    38       if (obj is Delegate || obj is EventHandler) return;
    39       if (obj.GetType().IsSubclassOfRawGeneric(typeof(EventHandler<>))) return;
    40       if (obj.GetType().GetElementType() != null) {
    41         Type elementType = obj.GetType().GetElementType();
     48      if (obj is Delegate || obj is EventHandler) return;
     49      Type type = obj.GetType();
     50      if (type.IsSubclassOfRawGeneric(typeof(EventHandler<>))) return;
     51      if (type.IsPrimitive || type == typeof(string) || type == typeof(decimal)) return;
     52      if (type.IsArray) {
     53        Type elementType = type.GetElementType();
    4254        if (elementType.IsPrimitive || elementType == typeof(string) || elementType == typeof(decimal)) return;
    4355      }
     
    4557      objects.Add(obj);
    4658
    47       IEnumerable enumerable = obj as IEnumerable;
    48       if (enumerable != null) {
    49         foreach (object value in enumerable) {
    50           value.CollectObjectGraphObjects(objects);
     59      if (typeof(Type).IsInstanceOfType(obj)) return; // avoid infinite recursion
     60      if (type.IsSubclassOfRawGeneric(typeof(ThreadLocal<>))) return; // avoid stack overflow when the field `ConcurrentStack<int> s_availableIndices` grows large
     61
     62      // performance critical to handle dictionaries in a special way
     63      var dictionary = obj as IDictionary;
     64      if (dictionary != null) {
     65        foreach (object value in dictionary.Keys) {
     66          CollectObjectGraphObjects(value, objects);
    5167        }
    52       } else {
    53         foreach (FieldInfo f in obj.GetType().GetAllFields()) {
    54           f.GetValue(obj).CollectObjectGraphObjects(objects);
     68        foreach (object value in dictionary.Values) {
     69          CollectObjectGraphObjects(value, objects);
    5570        }
     71        return;
    5672      }
     73
     74      if (type.IsArray) {
     75        var array = obj as Array;
     76        foreach (object value in array) {
     77          CollectObjectGraphObjects(value, objects);
     78        }
     79        return;
     80      }
     81
     82      foreach (FieldInfo f in type.GetAllFields()) {
     83        f.GetValue(obj).CollectObjectGraphObjects(objects);
     84      }     
    5785    }
    5886  }
Note: See TracChangeset for help on using the changeset viewer.