Summary

Class:FakeXrmEasy.Extensions.ObjectExtensions
Assembly:FakeXrmEasy
File(s):F:\Git\fake-xrm-easy\FakeXrmEasy.Shared\Extensions\ObjectExtensions.cs
Covered lines:65
Uncovered lines:13
Coverable lines:78
Total lines:172
Line coverage:83.3%
Branch coverage:73.3%

Metrics

MethodCyclomatic ComplexitySequence CoverageBranch Coverage
IsPrimitive(...)2100100
GetFieldInfo(...)3100100
GetFieldValue(...)300
SetFieldValue(...)377.7860
Copy(...)1100100
InternalCopy(...)79692.31
RecursiveCopyBaseTypePrivateFields(...)3100100
CopyFields(...)593.3380
Copy(...)1100100
.cctor()1100100

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    {
 614        private static readonly MethodInfo CloneMethod = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPub
 15
 16        public static bool IsPrimitive(this Type type)
 893125617        {
 1084031518             if (type == typeof(String)) return true;
 702219719            return (type.IsValueType & type.IsPrimitive);
 893125620        }
 21
 22        private static FieldInfo GetFieldInfo(Type type, string fieldName)
 17201823        {
 24            FieldInfo fieldInfo;
 25            do
 34585426            {
 34585427                fieldInfo = type.GetField(fieldName,
 34585428                       BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
 34585429                type = type.BaseType;
 34585430            }
 34585431             while (fieldInfo == null && type != null);
 17201832            return fieldInfo;
 17201833        }
 34
 35        public static object GetFieldValue(this object obj, string fieldName)
 036        {
 037             if (obj == null)
 038                throw new ArgumentNullException("obj");
 039            Type objType = obj.GetType();
 040            FieldInfo fieldInfo = GetFieldInfo(objType, fieldName);
 041             if (fieldInfo == null)
 042                throw new ArgumentOutOfRangeException("fieldName",
 043                  string.Format("Couldn't find field {0} in type {1}", fieldName, objType.FullName));
 044            return fieldInfo.GetValue(obj);
 045        }
 46
 47        public static void SetFieldValue(this object obj, string fieldName, object val)
 17201848        {
 17201849             if (obj == null)
 050                throw new ArgumentNullException("obj");
 17201851            Type objType = obj.GetType();
 17201852            FieldInfo fieldInfo = GetFieldInfo(objType, fieldName);
 17201853             if (fieldInfo == null)
 054                throw new ArgumentOutOfRangeException("fieldName",
 055                  string.Format("Couldn't find field {0} in type {1}", fieldName, objType.FullName));
 17201856            fieldInfo.SetValue(obj, val);
 17201857        }
 58
 59
 60        public static Object Copy(this Object originalObject)
 631961        {
 631962            return InternalCopy(originalObject, new Dictionary<Object, Object>(new ReferenceEqualityComparer()));
 631963        }
 64
 65        private static Object InternalCopy(Object originalObject, IDictionary<Object, Object> visited)
 624723266        {
 1188039867             if (originalObject == null) return null;
 61406668            var typeToReflect = originalObject.GetType();
 61987469             if (IsPrimitive(typeToReflect)) return originalObject;
 69154670             if (visited.ContainsKey(originalObject)) return visited[originalObject];
 52497071             if (typeof(Delegate).IsAssignableFrom(typeToReflect)) return null;
 52497072            var cloneObject = CloneMethod.Invoke(originalObject, null);
 52497073             if (typeToReflect.IsArray)
 1954974            {
 1954975                var arrayType = typeToReflect.GetElementType();
 1954976                 if (IsPrimitive(arrayType) == false)
 1804677                {
 1804678                    Array clonedArray = (Array)cloneObject;
 25795879                    clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), v
 1804680                }
 1954981            }
 52497082            visited.Add(originalObject, cloneObject);
 52497083            CopyFields(originalObject, visited, cloneObject, typeToReflect);
 52497084            RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect);
 52497085            return cloneObject;
 624723286        }
 87
 88        private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary<object, object> visite
 201000289        {
 201000290             if (typeToReflect.BaseType != null)
 148503291            {
 148503292                RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType);
 763035393                CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | Binding
 148503294            }
 201000295        }
 96
 97        private static void CopyFields(object originalObject, IDictionary<object, object> visited, object cloneObject, T
 201000298        {
 2262528899            foreach (FieldInfo fieldInfo in typeToReflect.GetFields(bindingFlags))
 8297641100            {
 8297641101                 if (filter != null && filter(fieldInfo) == false) continue;
 10594281102                 if (IsPrimitive(fieldInfo.FieldType)) continue;
 6001001103                var originalFieldValue = fieldInfo.GetValue(originalObject);
 6001001104                var clonedFieldValue = InternalCopy(originalFieldValue, visited);
 6001001105                fieldInfo.SetValue(cloneObject, clonedFieldValue);
 6001001106            }
 2010002107        }
 108
 109        public static T Copy<T>(this T original)
 6319110        {
 6319111            return (T)Copy((Object)original);
 6319112        }
 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
 145        public ArrayTraverse(Array array)
 146        {
 147            maxLengths = new int[array.Rank];
 148            for (int i = 0; i < array.Rank; ++i)
 149            {
 150                maxLengths[i] = array.GetLength(i) - 1;
 151            }
 152            Position = new int[array.Rank];
 153        }
 154
 155        public bool Step()
 156        {
 157            for (int i = 0; i < Position.Length; ++i)
 158            {
 159                if (Position[i] < maxLengths[i])
 160                {
 161                    Position[i]++;
 162                    for (int j = 0; j < i; j++)
 163                    {
 164                        Position[j] = 0;
 165                    }
 166                    return true;
 167                }
 168            }
 169            return false;
 170        }
 171    }
 172}