public static void SetMemberSelector(this CustomType customType, IMemberSelector memberSelector)
        {
            ArgumentUtility.CheckNotNull("customType", customType);
            ArgumentUtility.CheckNotNull("memberSelector", memberSelector);

            PrivateInvoke.SetNonPublicField(customType, "_memberSelector", memberSelector);
        }
Beispiel #2
0
        public void SetUp()
        {
            _memberSelectorMock = MockRepository.GenerateStrictMock <IMemberSelector>();

            _name       = "TypeName";
            _namespace  = "MyNamespace";
            _attributes = (TypeAttributes)7;

            _customType = new TestableCustomType(
                _name,
                _namespace,
                _attributes,
                genericTypeDefinition: null,
                typeArguments: Type.EmptyTypes)
            {
                NestedTypes  = new[] { ReflectionObjectMother.GetSomeType() },
                Interfaces   = new[] { typeof(IDisposable) },
                Fields       = new[] { ReflectionObjectMother.GetSomeField() },
                Constructors = new[] { ReflectionObjectMother.GetSomeConstructor() },
                Methods      = new[] { ReflectionObjectMother.GetSomeMethod() },
                Properties   = new[] { ReflectionObjectMother.GetSomeProperty() },
                Events       = new[] { ReflectionObjectMother.GetSomeEvent() }
            };
            _customType.SetMemberSelector(_memberSelectorMock);

            _typeArgument = ReflectionObjectMother.GetSomeType();
            _genericTypeUnderlyingDefinition = typeof(IList <>);
            _genericType = CustomTypeObjectMother.Create(
                name: "GenericType`1", genericTypeDefinition: _genericTypeUnderlyingDefinition, typeArguments: new[] { _typeArgument });

            _typeParameter         = ReflectionObjectMother.GetSomeGenericParameter();
            _genericTypeDefinition = CustomTypeObjectMother.Create(name: "GenericTypeDefinition`1", typeArguments: new[] { _typeParameter });
        }
        public virtual void ValidateMembersRecursively(object value, IMemberSelector selector, UnityEngine.Object root, ref List <ValidationResult> results)
        {
            if (results == null)
            {
                results = new List <ValidationResult>();
            }

            if (object.ReferenceEquals(value, null))
            {
                return;
            }

            HashSet <object>     seenReferences = new HashSet <object>(ReferenceEqualityComparer <object> .Default);
            HashSet <MemberInfo> seenMembers    = new HashSet <MemberInfo>(FastMemberComparer.Instance);

            foreach (var member in selector.SelectMembers(value.GetType()))
            {
                var memberValue     = GetMemberValue(member, value, results);
                var memberValueType = memberValue == null?member.GetReturnType() : memberValue.GetType();

                ValidateMemberRecursive(value, member, memberValue, memberValueType, selector, root, new List <ValidationPathStep>()
                {
                    new ValidationPathStep()
                    {
                        Member     = member,
                        Value      = memberValue,
                        StepString = member.Name
                    }
                }, seenReferences, seenMembers, results, 0);
            }
        }
Beispiel #4
0
        /// <inheritdoc/>
        public override bool TryRecycle(
            int oldIndex,
            int newIndex,
            object item,
            IMemberSelector selector)
        {
            var container = ContainerFromIndex(oldIndex);

            if (container == null)
            {
                throw new IndexOutOfRangeException("Could not recycle container: not materialized.");
            }

            var i = selector != null?selector.Select(item) : item;

            container.SetValue(ContentProperty, i);

            if (!(item is IControl))
            {
                container.DataContext = i;
            }

            var info = MoveContainer(oldIndex, newIndex, i);

            RaiseRecycled(new ItemContainerEventArgs(info));

            return(true);
        }
Beispiel #5
0
        public static MutableType Create(
            Type baseType                  = null,
            string name                    = "MyMutableType",
            string @namespace              = "MyNamespace",
            TypeAttributes attributes      = TypeAttributes.Public | TypeAttributes.BeforeFieldInit,
            MutableType declaringType      = null,
            IMemberSelector memberSelector = null,
            IInterfaceMappingComputer interfaceMappingComputer = null,
            IMutableMemberFactory mutableMemberFactory         = null,
            bool copyCtorsFromBase = false)
        {
            baseType = baseType ?? typeof(UnspecifiedType);
            // Declaring type stays null.

            memberSelector           = memberSelector ?? new MemberSelector(new BindingFlagsEvaluator());
            interfaceMappingComputer = interfaceMappingComputer ?? new InterfaceMappingComputer();
            mutableMemberFactory     = mutableMemberFactory ?? new MutableMemberFactory(new RelatedMethodFinder());

            var mutableType = new MutableType(declaringType, baseType, name, @namespace, attributes, interfaceMappingComputer, mutableMemberFactory);

            mutableType.SetMemberSelector(memberSelector);

            if (copyCtorsFromBase)
            {
                CopyConstructors(baseType, mutableType);
            }

            return(mutableType);
        }
 /// <inheritdoc/>
 public virtual bool TryRecycle(
     int oldIndex,
     int newIndex,
     object item,
     IMemberSelector selector)
 {
     return(false);
 }
Beispiel #7
0
 public DynamicBuilder(
     IInstanceFactory <T> instanceFactory = null,
     IPropertySetter propertySetter       = null,
     IMemberSelector memberSelector       = null)
 {
     InstanceFactory = instanceFactory ?? new ConstructorInstanceFactory <T>();
     PropertySetter  = propertySetter ?? new PropertySetter();
     MemberSelector  = memberSelector ?? new MemberSelector();
     _properties     = new ReadOnlyCollection <PropertyInfo>(MemberSelector.SelectProperties(typeof(T)).ToList());
 }
        /// <inheritdoc/>
        public ItemContainerInfo Materialize(
            int index,
            object item,
            IMemberSelector selector)
        {
            var i = selector != null ? selector.Select(item) : item;
            var container = new ItemContainerInfo(CreateContainer(i), item, index);

            _containers.Add(container.Index, container);
            Materialized?.Invoke(this, new ItemContainerEventArgs(container));

            return container;
        }
        /// <inheritdoc/>
        public ItemContainerInfo Materialize(
            int index,
            object item,
            IMemberSelector selector)
        {
            var i = selector != null?selector.Select(item) : item;

            var container = new ItemContainerInfo(CreateContainer(i), item, index);

            _containers.Add(container.Index, container);
            Materialized?.Invoke(this, new ItemContainerEventArgs(container));

            return(container);
        }
Beispiel #10
0
        public void SetUp()
        {
            _memberSelectorMock           = MockRepository.GenerateStrictMock <IMemberSelector>();
            _interfaceMappingComputerMock = MockRepository.GenerateStrictMock <IInterfaceMappingComputer>();
            _mutableMemberFactoryMock     = MockRepository.GenerateStrictMock <IMutableMemberFactory>();

            _mutableType = MutableTypeObjectMother.Create(
                name: "MyAbcType",
                baseType: typeof(DomainType),
                memberSelector: _memberSelectorMock,
                interfaceMappingComputer: _interfaceMappingComputerMock,
                mutableMemberFactory: _mutableMemberFactoryMock);

            _mutableTypeWithoutMocks = MutableTypeObjectMother.Create(baseType: typeof(DomainType));
        }
Beispiel #11
0
        public static CustomType Create(
            IMemberSelector memberSelector = null,
            Type baseType             = null,
            Type declaringType        = null,
            string name               = "CustomType",
            string @namespace         = null,
            TypeAttributes attributes = (TypeAttributes)7,
            IEnumerable <ICustomAttributeData> customAttributeDatas = null,
            IEnumerable <Type> nestedTypes             = null,
            IEnumerable <Type> interfaces              = null,
            IEnumerable <FieldInfo> fields             = null,
            IEnumerable <ConstructorInfo> constructors = null,
            IEnumerable <MethodInfo> methods           = null,
            IEnumerable <PropertyInfo> properties      = null,
            IEnumerable <EventInfo> events             = null,
            Type genericTypeDefinition       = null,
            IEnumerable <Type> typeArguments = null)
        {
            memberSelector = memberSelector ?? new MemberSelector(new BindingFlagsEvaluator());
            baseType       = baseType ?? typeof(UnspecifiedType);
            // Declaring type stays null.
            // Generic type definition stays null.
            var typeArgs = (typeArguments ?? Type.EmptyTypes).ToList();

            var customType =
                new TestableCustomType(
                    name,
                    @namespace,
                    attributes,
                    genericTypeDefinition,
                    typeArgs)
            {
                CustomAttributeDatas = customAttributeDatas ?? new ICustomAttributeData[0],
                NestedTypes          = nestedTypes ?? Type.EmptyTypes,
                Interfaces           = interfaces ?? Type.EmptyTypes,
                Fields       = fields ?? new FieldInfo[0],
                Constructors = constructors ?? new ConstructorInfo[0],
                Methods      = methods ?? new MethodInfo[0],
                Properties   = properties ?? new PropertyInfo[0],
                Events       = events ?? new EventInfo[0]
            };

            customType.SetMemberSelector(memberSelector);
            customType.CallSetBaseType(baseType);
            customType.CallSetDeclaringType(declaringType);

            return(customType);
        }
Beispiel #12
0
        public static MutableGenericParameter Create(
            int position      = 7,
            string name       = "T",
            string @namespace = "MyNs",
            GenericParameterAttributes genericParameterAttributes = GenericParameterAttributes.None,
            IEnumerable <Type> constraints = null,
            IMemberSelector memberSelector = null)
        {
            constraints    = constraints ?? Type.EmptyTypes;
            memberSelector = memberSelector ?? new MemberSelector(new BindingFlagsEvaluator());

            var genericParameter = new MutableGenericParameter(position, name, @namespace, genericParameterAttributes);

            genericParameter.SetGenericParameterConstraints(constraints);

            return(genericParameter);
        }
        public static TypeInstantiation Create(
            Type genericTypeDefinition       = null,
            IEnumerable <Type> typeArguments = null,
            TypeInstantiationContext instantiationContext = null,
            IMemberSelector memberSelector = null)
        {
            genericTypeDefinition = genericTypeDefinition ?? typeof(MyGenericType <>);
            typeArguments         = typeArguments ?? genericTypeDefinition.GetGenericArguments().Select(a => ReflectionObjectMother.GetSomeType());
            var instantiationInfo = new TypeInstantiationInfo(genericTypeDefinition, typeArguments);

            instantiationContext = instantiationContext ?? new TypeInstantiationContext();
            memberSelector       = memberSelector ?? new MemberSelector(new BindingFlagsEvaluator());

            var typeInstantiation = new TypeInstantiation(instantiationInfo, instantiationContext);

            typeInstantiation.SetMemberSelector(memberSelector);

            return(typeInstantiation);
        }
        public virtual void ValidateMembers(object value, IMemberSelector selector, UnityEngine.Object root, bool isCollectionElement, ref List <ValidationResult> results)
        {
            if (results == null)
            {
                results = new List <ValidationResult>();
            }

            if (object.ReferenceEquals(value, null))
            {
                return;
            }

            foreach (var member in selector.SelectMembers(value.GetType()))
            {
                var memberValue     = GetMemberValue(member, value, results);
                var memberValueType = memberValue == null?member.GetReturnType() : memberValue.GetType();

                ValidateMember(value, member, memberValue, memberValueType, root, isCollectionElement, ref results);
            }
        }
        /// <summary>
        /// Creates container controls for a collection of items.
        /// </summary>
        /// <param name="startingIndex">
        /// The index of the first item of the data in the containing collection.
        /// </param>
        /// <param name="items">The items.</param>
        /// <param name="selector">An optional member selector.</param>
        /// <returns>The created container controls.</returns>
        public IList<IControl> CreateContainers(
            int startingIndex,
            IEnumerable items,
            IMemberSelector selector)
        {
            Contract.Requires<ArgumentNullException>(items != null);

            int index = startingIndex;
            var result = new List<IControl>();

            foreach (var item in items)
            {
                var i = selector != null ? selector.Select(item) : item;
                var container = CreateContainer(i);
                result.Add(container);
            }

            AddContainers(startingIndex, result);
            _containersInitialized.OnNext(new ItemContainers(startingIndex, result));

            return result.Where(x => x != null).ToList();
        }
        /// <inheritdoc/>
        public IEnumerable<ItemContainer> Materialize(
            int startingIndex,
            IEnumerable items,
            IMemberSelector selector)
        {
            Contract.Requires<ArgumentNullException>(items != null);

            int index = startingIndex;
            var result = new List<ItemContainer>();

            foreach (var item in items)
            {
                var i = selector != null ? selector.Select(item) : item;
                var container = new ItemContainer(CreateContainer(i), item, index++);
                result.Add(container);
            }

            AddContainers(result);
            Materialized?.Invoke(this, new ItemContainerEventArgs(startingIndex, result));

            return result.Where(x => x != null).ToList();
        }
Beispiel #17
0
        /// <inheritdoc/>
        public IEnumerable <ItemContainer> Materialize(
            int startingIndex,
            IEnumerable items,
            IMemberSelector selector)
        {
            Contract.Requires <ArgumentNullException>(items != null);

            int index  = startingIndex;
            var result = new List <ItemContainer>();

            foreach (var item in items)
            {
                var i = selector != null?selector.Select(item) : item;

                var container = new ItemContainer(CreateContainer(i), item, index++);
                result.Add(container);
            }

            AddContainers(result);
            Materialized?.Invoke(this, new ItemContainerEventArgs(startingIndex, result));

            return(result.Where(x => x != null).ToList());
        }
Beispiel #18
0
        /// <inheritdoc/>
        public IEnumerable <IControl> Materialize(
            int startingIndex,
            IEnumerable items,
            IMemberSelector selector)
        {
            Contract.Requires <ArgumentNullException>(items != null);

            int index  = startingIndex;
            var result = new List <IControl>();

            foreach (var item in items)
            {
                var i = selector != null?selector.Select(item) : item;

                var container = CreateContainer(i);
                result.Add(container);
            }

            AddContainers(startingIndex, result);
            _containersInitialized.OnNext(new ItemContainers(startingIndex, result));

            return(result.Where(x => x != null).ToList());
        }
Beispiel #19
0
        public static MutableType CreateInterface(
            string name                                        = "MyMutableInterface",
            string @namespace                                  = "MyNamespace",
            TypeAttributes attributes                          = TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract,
            MutableType declaringType                          = null,
            IMemberSelector memberSelector                     = null,
            IRelatedMethodFinder relatedMethodFinder           = null,
            IInterfaceMappingComputer interfaceMappingComputer = null,
            IMutableMemberFactory mutableMemberFactory         = null)
        {
            // Declaring type stays null.

            memberSelector           = memberSelector ?? new MemberSelector(new BindingFlagsEvaluator());
            relatedMethodFinder      = relatedMethodFinder ?? new RelatedMethodFinder();
            interfaceMappingComputer = interfaceMappingComputer ?? new InterfaceMappingComputer();
            mutableMemberFactory     = mutableMemberFactory ?? new MutableMemberFactory(relatedMethodFinder);
            Assertion.IsTrue(attributes.IsSet(TypeAttributes.Interface | TypeAttributes.Abstract));

            var mutableType = new MutableType(declaringType, null, name, @namespace, attributes, interfaceMappingComputer, mutableMemberFactory);

            mutableType.SetMemberSelector(memberSelector);

            return(mutableType);
        }
        protected virtual bool TryValidateMemberRecursivelyAsCollection(object collection, MemberInfo collectionMember, IMemberSelector selector, UnityEngine.Object root, List <ValidationPathStep> pathSoFar, HashSet <object> seenReferences, HashSet <MemberInfo> seenMembers, List <ValidationResult> results, int scanDepth)
        {
            scanDepth++;

            if (collection is Array)
            {
                int index       = 0;
                var elementType = collection.GetType().GetElementType();

                if (elementType.IsPrimitive)
                {
                    if (!this.ValidatorLocator.PotentiallyHasValidatorsFor(collectionMember, elementType, true))
                    {
                        // Don't actually validate the items in the array
                        return(true);
                    }
                }

                foreach (var item in collection as Array)
                {
                    var path = pathSoFar.ToList();

                    path.Add(new ValidationPathStep()
                    {
                        Member     = collectionMember,
                        Value      = collection,
                        StepString = CollectionResolverUtilities.DefaultIndexToChildName(index)
                    });

                    var itemType = item == null ? elementType : item.GetType();

                    ValidateMemberRecursive(collection, collectionMember, item, itemType, selector, root, path, seenReferences, seenMembers, results, scanDepth, true);
                    index++;
                }

                return(true);
            }
            else if (collection is IList)
            {
                var elementType = collection.GetType().ImplementsOpenGenericInterface(typeof(IList <>)) ? collection.GetType().GetArgumentsOfInheritedOpenGenericInterface(typeof(IList <>))[0] : typeof(object);

                if (elementType.IsPrimitive)
                {
                    if (!this.ValidatorLocator.PotentiallyHasValidatorsFor(collectionMember, elementType, true))
                    {
                        // Don't actually validate the items in the list
                        return(true);
                    }
                }

                int index = 0;
                foreach (var item in collection as IList)
                {
                    var path = pathSoFar.ToList();

                    path.Add(new ValidationPathStep()
                    {
                        Member     = collectionMember,
                        Value      = collection,
                        StepString = CollectionResolverUtilities.DefaultIndexToChildName(index)
                    });

                    var itemType = item == null ? elementType : item.GetType();

                    ValidateMemberRecursive(collection, collectionMember, item, itemType, selector, root, path, seenReferences, seenMembers, results, scanDepth, true);
                    index++;
                }

                return(true);
            }
            else if (collection is IDictionary)
            {
                Type baseKeyType, baseValueType;

                if (collection.GetType().ImplementsOpenGenericInterface(typeof(IDictionary <,>)))
                {
                    var args = collection.GetType().GetArgumentsOfInheritedOpenGenericInterface(typeof(IDictionary <,>));
                    baseKeyType   = args[0];
                    baseValueType = args[1];
                }
                else
                {
                    baseKeyType   = typeof(object);
                    baseValueType = typeof(object);
                }

                foreach (DictionaryEntry entry in collection as IDictionary)
                {
                    var keyPath   = pathSoFar.ToList();
                    var valuePath = pathSoFar.ToList();

                    var keyStr = DictionaryKeyUtility.GetDictionaryKeyString(entry.Key);

                    keyPath.Add(new ValidationPathStep()
                    {
                        Member     = collectionMember,
                        Value      = entry.Key,
                        StepString = keyStr + "#key"
                    });

                    valuePath.Add(new ValidationPathStep()
                    {
                        Member     = collectionMember,
                        Value      = entry.Value,
                        StepString = keyStr
                    });

                    var keyType   = entry.Key == null ? baseKeyType : entry.Key.GetType();
                    var valueType = entry.Value == null ? baseValueType : entry.Value.GetType();

                    ValidateMemberRecursive(collection, collectionMember, entry.Key, keyType, selector, root, keyPath, seenReferences, seenMembers, results, scanDepth, true);
                    ValidateMemberRecursive(collection, collectionMember, entry.Value, valueType, selector, root, valuePath, seenReferences, seenMembers, results, scanDepth, true);
                }

                return(true);
            }
            else if (collection is IEnumerable && collection is ISerializable && collection is IDeserializationCallback && collection.GetType().ImplementsOpenGenericClass(typeof(HashSet <>)))
            {
                var elementType = collection.GetType().GetArgumentsOfInheritedOpenGenericType(typeof(HashSet <>))[0];

                foreach (var item in collection as IEnumerable)
                {
                    var path = pathSoFar.ToList();

                    path.Add(new ValidationPathStep()
                    {
                        Member     = collectionMember,
                        Value      = collection,
                        StepString = DictionaryKeyUtility.GetDictionaryKeyString(item)
                    });

                    var itemType = item == null ? elementType : item.GetType();
                    ValidateMemberRecursive(collection, collectionMember, item, itemType, selector, root, path, seenReferences, seenMembers, results, scanDepth, true);
                }

                return(true);
            }
            else if (collection is ICollection || collection.GetType().ImplementsOpenGenericInterface(typeof(ICollection <>)))
            {
                Type elementType;

                if (collection.GetType().ImplementsOpenGenericInterface(typeof(ICollection <>)))
                {
                    elementType = collection.GetType().GetArgumentsOfInheritedOpenGenericType(typeof(ICollection <>))[0];
                }
                else
                {
                    elementType = typeof(object);
                }

                int index = 0;
                foreach (var item in collection as IEnumerable)
                {
                    var path = pathSoFar.ToList();

                    path.Add(new ValidationPathStep()
                    {
                        Member     = collectionMember,
                        Value      = collection,
                        StepString = CollectionResolverUtilities.DefaultIndexToChildName(index)
                    });

                    var itemType = item == null ? elementType : item.GetType();
                    ValidateMemberRecursive(collection, collectionMember, item, itemType, selector, root, path, seenReferences, seenMembers, results, scanDepth, true);
                    index++;
                }

                return(true);
            }

            return(false);
        }
        public virtual void ValidateUnityObjectRecursively(UnityEngine.Object value, ref List <ValidationResult> results)
        {
            if (results == null)
            {
                results = new List <ValidationResult>();
            }

            if (object.ReferenceEquals(value, null))
            {
                return;
            }

            var type = value.GetType();

            bool odinSerialized             = type.IsDefined <ShowOdinSerializedPropertiesInInspectorAttribute>(inherit: true);
            bool odinSerializesUnityMembers = false;

            IMemberSelector selector;

            if (odinSerialized)
            {
                var policyOverride = value as IOverridesSerializationPolicy;

                if (policyOverride != null)
                {
                    selector = new SerializationPolicyMemberSelector(policyOverride.SerializationPolicy ?? SerializationPolicies.Unity);
                    odinSerializesUnityMembers = policyOverride.OdinSerializesUnityFields;
                }
                else
                {
                    selector = OdinMemberSelector;
                }
            }
            else
            {
                selector = UnityMemberSelector;
            }

            this.ValidateValue(value, value, ref results);

            HashSet <object>     seenReferences = new HashSet <object>(ReferenceEqualityComparer <object> .Default);
            HashSet <MemberInfo> seenMembers    = new HashSet <MemberInfo>(FastMemberComparer.Instance);

            foreach (var member in selector.SelectMembers(type))
            {
                IMemberSelector childSelector = selector;

                if (odinSerialized && !odinSerializesUnityMembers && UnitySerializationUtility.GuessIfUnityWillSerialize(member))
                {
                    childSelector = UnityMemberSelector;
                }

                var memberValue     = GetMemberValue(member, value, results);
                var memberValueType = memberValue == null?member.GetReturnType() : memberValue.GetType();

                ValidateMemberRecursive(value, member, memberValue, memberValueType, childSelector, value, new List <ValidationPathStep>()
                {
                    new ValidationPathStep()
                    {
                        Value = memberValue, Member = member, StepString = member.Name
                    }
                }, seenReferences, seenMembers, results, 0);
            }
        }
        protected virtual void ValidateMemberRecursive(object parentValue, MemberInfo member, object memberValue, Type memberValueType, IMemberSelector selector, UnityEngine.Object root, List <ValidationPathStep> pathSoFar, HashSet <object> seenReferences, HashSet <MemberInfo> seenMembers, List <ValidationResult> results, int scanDepth, bool isInCollection = false)
        {
            if (object.ReferenceEquals(parentValue, null))
            {
                return;
            }

            if (!isInCollection && member.IsStatic() && !seenMembers.Add(member))
            {
                return;
            }

            TempResults.Clear();
            {
                ValidateMember(parentValue, member, memberValue, memberValueType, root, isInCollection, ref TempResults);
                foreach (var result in TempResults)
                {
                    result.Path = pathSoFar.ToArray();
                }
                results.AddRange(TempResults);
            }
            TempResults.Clear();

            if (object.ReferenceEquals(memberValue, null))
            {
                return;
            }
            if (memberValue is UnityEngine.Object && !this.RecurseThroughUnityObjectReferences)
            {
                return;
            }

            if (!(memberValue is string) && !memberValue.GetType().IsPrimitive&& seenReferences.Contains(memberValue))
            {
                return;
            }

            if (scanDepth > this.MaxScanDepth)
            {
                if (this.WarnOnScanDepthReached)
                {
                    results.Add(new ValidationResult()
                    {
                        Message    = "Max scan depth reached",
                        ResultType = ValidationResultType.Warning,
                        Path       = pathSoFar.ToArray()
                    });
                }

                return;
            }

            seenReferences.Add(memberValue);
            scanDepth++;

            if (!TryValidateMemberRecursivelyAsCollection(memberValue, member, selector, root, pathSoFar, seenReferences, seenMembers, results, scanDepth))
            {
                foreach (var childMember in selector.SelectMembers(memberValue.GetType()))
                {
                    var path = pathSoFar.ToList();

                    var childMemberValue     = GetMemberValue(childMember, memberValue, results);
                    var childMemberValueType = childMemberValue == null?childMember.GetReturnType() : childMemberValue.GetType();

                    path.Add(new ValidationPathStep()
                    {
                        Member     = childMember,
                        Value      = childMemberValue,
                        StepString = childMember.Name
                    });

                    ValidateMemberRecursive(memberValue, childMember, childMemberValue, childMemberValueType, selector, root, path, seenReferences, seenMembers, results, scanDepth);
                }
            }
        }
        public virtual void ValidateMemberRecursive(object parentInstance, MemberInfo member, Type memberValueType, IMemberSelector selector, UnityEngine.Object root, ref List <ValidationResult> results)
        {
            if (results == null)
            {
                results = new List <ValidationResult>();
            }

            if (object.ReferenceEquals(parentInstance, null))
            {
                return;
            }

            HashSet <object>     seenReferences = new HashSet <object>(ReferenceEqualityComparer <object> .Default);
            HashSet <MemberInfo> seenMembers    = new HashSet <MemberInfo>(FastMemberComparer.Instance);

            var memberValue = GetMemberValue(member, parentInstance, results);

            ValidateMemberRecursive(parentInstance, member, memberValue, memberValueType, selector, root, new List <ValidationPathStep>()
            {
                new ValidationPathStep()
                {
                    Member     = member,
                    Value      = memberValue,
                    StepString = member.Name,
                }
            }, seenReferences, seenMembers, results, 0);
        }
 /// <inheritdoc/>
 public virtual bool TryRecycle(
     int oldIndex,
     int newIndex,
     object item,
     IMemberSelector selector)
 {
     return false;
 }