Example #1
0
        public void Init()
        {
            if (this.surrogate != null)
            {
                return;
            }
            if (this.copyByAssignment)
            {
                return;
            }

            if (this.type.IsArray)
            {
                this.investigateOwnership = !(this.elementType.IsCopyByAssignment || (this.elementType.Type.IsValueType && !this.elementType.InvestigateOwnership));
                return;
            }
            else
            {
                this.investigateOwnership = typeof(ICloneExplicit).GetTypeInfo().IsAssignableFrom(this.type) || this.surrogate != null;
            }

            // Retrieve field data
            List <CloneField> fieldData = new List <CloneField>();

            foreach (FieldInfo field in this.type.DeclaredFieldsDeep())
            {
                if (field.IsStatic)
                {
                    continue;
                }
                if (field.IsInitOnly)
                {
                    continue;
                }
                if (field.HasAttributeCached <ManuallyClonedAttribute>())
                {
                    continue;
                }
                if (field.DeclaringType.GetTypeInfo().HasAttributeCached <ManuallyClonedAttribute>())
                {
                    continue;
                }

                CloneFieldFlags     flags       = CloneFieldFlags.None;
                CloneFieldAttribute fieldAttrib = field.GetAttributesCached <CloneFieldAttribute>().FirstOrDefault();
                if (fieldAttrib != null)
                {
                    flags = fieldAttrib.Flags;
                }

                if (field.HasAttributeCached <DontSerializeAttribute>() && !flags.HasFlag(CloneFieldFlags.DontSkip))
                {
                    continue;
                }
                if (flags.HasFlag(CloneFieldFlags.Skip))
                {
                    continue;
                }

                CloneBehaviorAttribute behaviorAttrib = field.GetAttributesCached <CloneBehaviorAttribute>().FirstOrDefault();
                CloneType fieldType         = CloneProvider.GetCloneType(field.FieldType);
                bool      isAlwaysReference =
                    (behaviorAttrib != null) &&
                    (behaviorAttrib.TargetType == null || field.FieldType.GetTypeInfo().IsAssignableFrom(behaviorAttrib.TargetType.GetTypeInfo())) &&
                    (behaviorAttrib.Behavior == CloneBehavior.Reference);

                // Can this field own any objects itself?
                if (!this.investigateOwnership)
                {
                    bool fieldCanOwnObjects = true;
                    if (fieldType.IsCopyByAssignment)
                    {
                        fieldCanOwnObjects = false;
                    }
                    if (isAlwaysReference)
                    {
                        fieldCanOwnObjects = false;
                    }
                    if (fieldType.Type.IsValueType && !fieldType.InvestigateOwnership)
                    {
                        fieldCanOwnObjects = false;
                    }

                    if (fieldCanOwnObjects)
                    {
                        this.investigateOwnership = true;
                    }
                }

                CloneField fieldEntry = new CloneField(field, fieldType, flags, behaviorAttrib, isAlwaysReference);
                fieldData.Add(fieldEntry);
            }
            this.fieldData = fieldData.ToArray();

            // Build precompile functions for setup and (partially) assignment
            this.CompileAssignmentFunc();
            this.CompileSetupFunc();
            this.CompileValueAssignmentFunc();
            this.CompileValueSetupFunc();
        }
Example #2
0
        public void Init()
        {
            if (this.surrogate != null) return;
            if (this.plainOldData) return;

            if (this.type.IsArray)
            {
                this.investigateOwnership = !(this.elementType.IsPlainOldData || (this.elementType.Type.IsValueType && !this.elementType.InvestigateOwnership));
                return;
            }
            else
            {
                this.investigateOwnership = typeof(ICloneExplicit).IsAssignableFrom(this.type) || this.surrogate != null;
            }

            // Retrieve field data
            List<CloneField> fieldData = new List<CloneField>();
            foreach (FieldInfo field in this.type.GetAllFields(ReflectionHelper.BindInstanceAll))
            {
                if (field.IsInitOnly) continue;
                if (field.HasAttributeCached<ManuallyClonedAttribute>()) continue;
                if (field.DeclaringType.HasAttributeCached<ManuallyClonedAttribute>()) continue;

                CloneFieldFlags flags = CloneFieldFlags.None;
                CloneFieldAttribute fieldAttrib = field.GetAttributesCached<CloneFieldAttribute>().FirstOrDefault();
                if (fieldAttrib != null) flags = fieldAttrib.Flags;

                if (field.HasAttributeCached<DontSerializeAttribute>() && !flags.HasFlag(CloneFieldFlags.DontSkip))
                    continue;
                if (flags.HasFlag(CloneFieldFlags.Skip))
                    continue;

                CloneBehaviorAttribute behaviorAttrib = field.GetAttributesCached<CloneBehaviorAttribute>().FirstOrDefault();
                CloneType fieldType = CloneProvider.GetCloneType(field.FieldType);
                bool isAlwaysReference =
                    (behaviorAttrib != null) &&
                    (behaviorAttrib.TargetType == null || field.FieldType.IsAssignableFrom(behaviorAttrib.TargetType)) &&
                    (behaviorAttrib.Behavior == CloneBehavior.Reference);

                // Can this field own any objects itself?
                if (!this.investigateOwnership)
                {
                    bool fieldCanOwnObjects = true;
                    if (fieldType.IsPlainOldData)
                        fieldCanOwnObjects = false;
                    if (isAlwaysReference)
                        fieldCanOwnObjects = false;
                    if (fieldType.Type.IsValueType && !fieldType.InvestigateOwnership)
                        fieldCanOwnObjects = false;

                    if (fieldCanOwnObjects)
                        this.investigateOwnership = true;
                }

                CloneField fieldEntry = new CloneField(field, fieldType, flags, behaviorAttrib, isAlwaysReference);
                fieldData.Add(fieldEntry);
            }
            this.fieldData = fieldData.ToArray();

            // Build precompile functions for setup and (partially) assignment
            this.CompileAssignmentFunc();
            this.CompileSetupFunc();
            this.CompileValueAssignmentFunc();
            this.CompileValueSetupFunc();
        }