Summary

Class:FakeXrmEasy.Extensions.ArrayTraverse
Assembly:FakeXrmEasy
File(s):F:\Git\fake-xrm-easy\FakeXrmEasy.Shared\Extensions\ObjectExtensions.cs
Covered lines:20
Uncovered lines:3
Coverable lines:23
Total lines:172
Line coverage:86.9%
Branch coverage:87.5%

Metrics

MethodCyclomatic ComplexitySequence CoverageBranch Coverage
.ctor(...)2100100
Step()477.7885.71

File(s)

F:\Git\fake-xrm-easy\FakeXrmEasy.Shared\Extensions\ObjectExtensions.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Reflection;
 4
 5namespace FakeXrmEasy.Extensions
 6{
 7    //taken from:
 8    //https://github.com/Burtsev-Alexey/net-object-deep-copy/blob/master/ObjectExtensions.cs
 9    /// <summary>
 10    /// Deep cloning of the object
 11    /// </summary>
 12    public static class ObjectExtensions
 13    {
 14        private static readonly MethodInfo CloneMethod = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPub
 15
 16        public static bool IsPrimitive(this Type type)
 17        {
 18            if (type == typeof(String)) return true;
 19            return (type.IsValueType & type.IsPrimitive);
 20        }
 21
 22        private static FieldInfo GetFieldInfo(Type type, string fieldName)
 23        {
 24            FieldInfo fieldInfo;
 25            do
 26            {
 27                fieldInfo = type.GetField(fieldName,
 28                       BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
 29                type = type.BaseType;
 30            }
 31            while (fieldInfo == null && type != null);
 32            return fieldInfo;
 33        }
 34
 35        public static object GetFieldValue(this object obj, string fieldName)
 36        {
 37            if (obj == null)
 38                throw new ArgumentNullException("obj");
 39            Type objType = obj.GetType();
 40            FieldInfo fieldInfo = GetFieldInfo(objType, fieldName);
 41            if (fieldInfo == null)
 42                throw new ArgumentOutOfRangeException("fieldName",
 43                  string.Format("Couldn't find field {0} in type {1}", fieldName, objType.FullName));
 44            return fieldInfo.GetValue(obj);
 45        }
 46
 47        public static void SetFieldValue(this object obj, string fieldName, object val)
 48        {
 49            if (obj == null)
 50                throw new ArgumentNullException("obj");
 51            Type objType = obj.GetType();
 52            FieldInfo fieldInfo = GetFieldInfo(objType, fieldName);
 53            if (fieldInfo == null)
 54                throw new ArgumentOutOfRangeException("fieldName",
 55                  string.Format("Couldn't find field {0} in type {1}", fieldName, objType.FullName));
 56            fieldInfo.SetValue(obj, val);
 57        }
 58
 59
 60        public static Object Copy(this Object originalObject)
 61        {
 62            return InternalCopy(originalObject, new Dictionary<Object, Object>(new ReferenceEqualityComparer()));
 63        }
 64
 65        private static Object InternalCopy(Object originalObject, IDictionary<Object, Object> visited)
 66        {
 67            if (originalObject == null) return null;
 68            var typeToReflect = originalObject.GetType();
 69            if (IsPrimitive(typeToReflect)) return originalObject;
 70            if (visited.ContainsKey(originalObject)) return visited[originalObject];
 71            if (typeof(Delegate).IsAssignableFrom(typeToReflect)) return null;
 72            var cloneObject = CloneMethod.Invoke(originalObject, null);
 73            if (typeToReflect.IsArray)
 74            {
 75                var arrayType = typeToReflect.GetElementType();
 76                if (IsPrimitive(arrayType) == false)
 77                {
 78                    Array clonedArray = (Array)cloneObject;
 79                    clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), v
 80                }
 81            }
 82            visited.Add(originalObject, cloneObject);
 83            CopyFields(originalObject, visited, cloneObject, typeToReflect);
 84            RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect);
 85            return cloneObject;
 86        }
 87
 88        private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary<object, object> visite
 89        {
 90            if (typeToReflect.BaseType != null)
 91            {
 92                RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType);
 93                CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | Binding
 94            }
 95        }
 96
 97        private static void CopyFields(object originalObject, IDictionary<object, object> visited, object cloneObject, T
 98        {
 99            foreach (FieldInfo fieldInfo in typeToReflect.GetFields(bindingFlags))
 100            {
 101                if (filter != null && filter(fieldInfo) == false) continue;
 102                if (IsPrimitive(fieldInfo.FieldType)) continue;
 103                var originalFieldValue = fieldInfo.GetValue(originalObject);
 104                var clonedFieldValue = InternalCopy(originalFieldValue, visited);
 105                fieldInfo.SetValue(cloneObject, clonedFieldValue);
 106            }
 107        }
 108
 109        public static T Copy<T>(this T original)
 110        {
 111            return (T)Copy((Object)original);
 112        }
 113    }
 114
 115    public class ReferenceEqualityComparer : EqualityComparer<Object>
 116    {
 117        public override bool Equals(object x, object y)
 118        {
 119            return ReferenceEquals(x, y);
 120        }
 121
 122        public override int GetHashCode(object obj)
 123        {
 124            if (obj == null) return 0;
 125            return obj.GetHashCode();
 126        }
 127    }
 128
 129    public static class ArrayExtensions
 130    {
 131        public static void ForEach(this Array array, Action<Array, int[]> action)
 132        {
 133            if (array.LongLength == 0) return;
 134            ArrayTraverse walker = new ArrayTraverse(array);
 135            do action(array, walker.Position);
 136            while (walker.Step());
 137        }
 138    }
 139
 140    internal class ArrayTraverse
 141    {
 142        public int[] Position;
 143        private int[] maxLengths;
 144
 17901145        public ArrayTraverse(Array array)
 17901146        {
 17901147            maxLengths = new int[array.Rank];
 71604148             for (int i = 0; i < array.Rank; ++i)
 17901149            {
 17901150                maxLengths[i] = array.GetLength(i) - 1;
 17901151            }
 17901152            Position = new int[array.Rank];
 17901153        }
 154
 155        public bool Step()
 239912156        {
 515626157             for (int i = 0; i < Position.Length; ++i)
 239912158            {
 239912159                 if (Position[i] < maxLengths[i])
 222011160                {
 222011161                    Position[i]++;
 444022162                     for (int j = 0; j < i; j++)
 0163                    {
 0164                        Position[j] = 0;
 0165                    }
 222011166                    return true;
 167                }
 17901168            }
 17901169            return false;
 239912170        }
 171    }
 172}