示例#1
0
        /// <summary>Traverses the object graph rooted at <c>obj</c> by reflecting over the objects in the object's fields,
        ///     their fields, etc.  For each object visited in the graph, calls objFilter.  If objFilter
        ///     returns false, the object passed to objFilter isn't recursed, else it is.
        /// 
        ///     If a non-null value is provided for <c>parent</c>, any references to the <c>parent</c> object are
        ///     ignored and are neither traversed nor passed to objFilter.
        /// 
        ///     <c>cookie</c> is a caller-defined state object that is passed to objFilter directly.
        /// </summary>
        /// 
        /// <param name="cookie"></param>
        /// <param name="obj"></param>
        /// <param name="parent"></param>
        /// <param name="objFilter"></param>
        /// 
        /// <returns>A list of all the objects in the graph, not including those that were excluded
        ///     by objFilter.  This list will not contain duplicates, even if an object
        ///     was encountered multiple times during the recursion.</returns>
        public ICollection RecurseObjectGraph(Object cookie, Object obj, Object parent, ProcessObjectFilterDelegate objFilter)
        {
            if (obj == null) {
                throw new ArgumentNullException("obj");
            }

            if (objFilter == null) {
                throw new ArgumentNullException("obj");
            }

            //Start the list of objects
            ArrayList objList = new ArrayList();

            RecurseObjectGraphInternal(objList, cookie, null, obj, parent, objFilter);

            return objList;
        }
示例#2
0
        /// <summary>Internal recursive function that actually does the recursion</summary>
        /// 
        /// <param name="cookie"></param>
        /// <param name="field"></param>
        /// <param name="obj"></param>
        /// <param name="parent"></param>
        /// <param name="objFilter"></param>
        private void RecurseObjectGraphInternal(IList objList, Object cookie, FieldInfo field, Object obj, Object parent, ProcessObjectFilterDelegate objFilter)
        {
            //First, pass this object through the object processor.  If it indicates
            //not to recurse further, stop now
            if (!objFilter(cookie, field, obj, parent)) {
                return;
            }

            //Add this object to the list of objects that have been processed
            objList.Add(obj);

            //Get all the fields for this type, and for each one, process its object graph
            foreach (FieldInfo fi in GetTypeFields(obj.GetType())) {
                //Process the value of the field
                RecurseFieldValue(objList,
                                           cookie,
                                           fi,
                                           fi.GetValue(obj),
                                           obj,
                                           parent,
                                           objFilter);
            }

            if (obj is Array) {
                //An array object.  Process each of its elements as well
                foreach (Object arrayObj in (Array)obj) {
                RecurseFieldValue(objList,
                                           cookie,
                                           field,
                                           arrayObj,
                                           obj,
                                           parent,
                                           objFilter);
                }
            }
        }
示例#3
0
        /// Encapsulates the logic to recurse the (potentially null) value of a field
        private void RecurseFieldValue(IList objList, Object cookie, FieldInfo field, Object fieldValue, Object obj, Object parent, ProcessObjectFilterDelegate objFilter)
        {
            //If the field value is null, ignore it
            if (fieldValue == null) {
                return;
            }

            //If this is the current object's parent, ignore it, since it will
            //already have been processed
            if (fieldValue == parent) {
                return;
            }

            //If this is already in the list of objects in the graph, don't process
            //it again
            if (objList.Contains(fieldValue)) {
                return;
            }

            //Process this object's graph
            RecurseObjectGraphInternal(objList,
                                       cookie,
                                       field,
                                       fieldValue,
                                       obj,
                                       objFilter);
        }