Exemple #1
0
        protected override T CloneComplex <T>(T source, CloningMode mode)
        {
            var rank = _type.GetArrayRank();

            if (rank > 1)
            {
                throw new ArgumentException("Only one-dimensional arrays are supported.", nameof(source));
            }
            var arr = source as Array;

            switch (mode)
            {
            case CloningMode.Deep:
                var elemType = _type.GetElementType();
                var newArray = Array.CreateInstance(elemType, arr.Length);
                _cloned.Add(source, newArray);
                for (var i = 0; i < arr.Length; i++)
                {
                    var value = CloneMakerFactory.GetCloneMaker(arr.GetValue(i), mode, _typeMembers, _cloned).Clone(arr.GetValue(i), mode);
                    newArray.SetValue(value, i);
                }

                return((T)(object)newArray);

            case CloningMode.Shallow:
                return((T)arr.Clone());

            default:
                throw new ArgumentException("Deep or shallow mode should be defined.", nameof(mode));
            }
        }
Exemple #2
0
 public T Clone <T>(T source)
 {
     try
     {
         return(CloneMakerFactory.GetCloneMaker(source, CloningMode.Deep, _typeMembers, _cloned).Clone(source, CloningMode.Deep));
     }
     catch (ArgumentException ex)
     {
         //log it
         throw;
     }
 }
Exemple #3
0
        protected override T CloneComplex <T>(T source, CloningMode mode)
        {
            var addMethod     = _type.GetMethod(AddMethod, BindingFlags.Instance | BindingFlags.Public);
            var collection    = source as IEnumerable;
            var newCollection = (ICollection)Activator.CreateInstance(_type);

            _cloned.Add(source, newCollection);
            foreach (var item in collection)
            {
                var value = CloneMakerFactory.GetCloneMaker(item, mode, _typeMembers, _cloned).Clone(item, mode);
                addMethod.Invoke(newCollection, new object[] { value });
            }
            return((T)newCollection);
        }
Exemple #4
0
        private T CloneWithMembers <T>(T source, IReadOnlyCollection <Tuple <MemberInfo, MemberTypes, CloningMode> > members)
        {
            var copy = CreateInstance(source);

            _cloned.Add(source, copy);

            foreach (var member in members)
            {
                if (member.Item3 == CloningMode.Ignore)
                {
                    continue;
                }

                Func <object>           valueGetter;
                Action <object, object> valueSetter;
                Func <object>           structValueGetter;
                Action <object, object> structValueSetter;
                switch (member.Item2)
                {
                case MemberTypes.Property:
                    var property = member.Item1 as PropertyInfo;
                    valueGetter       = () => CreatePropGetter <T, object>(property)(source);
                    valueSetter       = (target, value) => CreatePropSetter <T, object>(property)((T)target, value);
                    structValueGetter = () => property.GetValue(source);
                    structValueSetter = (target, value) => property.SetValue(target, value);
                    break;

                case MemberTypes.Field:
                    var field = member.Item1 as FieldInfo;
                    valueGetter       = () => CreateGetter <T, object>(field)(source);
                    valueSetter       = (target, value) => CreateSetter <T, object>(field)((T)target, value);
                    structValueGetter = () => field.GetValue(source);
                    structValueSetter = (target, value) => field.SetValue(target, value);
                    break;

                default:
                    throw new ArgumentException("Only filed and property cloning supported.");
                }

                object sourceValue = null;
                if (_type.IsValueType)
                {
                    sourceValue = structValueGetter();
                }
                else
                {
                    sourceValue = valueGetter();
                }

                if (sourceValue == null)
                {
                    continue;
                }
                var clone = CloneMakerFactory.GetCloneMaker(sourceValue, member.Item3, _typeMembers, _cloned).Clone(sourceValue, member.Item3);
                if (_type.IsValueType)
                {
                    object boxed = copy;
                    structValueSetter(boxed, clone);
                    copy            = (T)boxed;
                    _cloned[source] = copy;
                }
                else
                {
                    valueSetter(copy, clone);
                }
            }
            return(copy);
        }