From e6ee5a708a499a874783f2f11cf2a4b66ce249f1 Mon Sep 17 00:00:00 2001 From: Gameleon12 Date: Wed, 8 Oct 2014 14:06:24 +0200 Subject: [PATCH 1/2] Updated for compatibility with new TypeInfo API Updated for compatibility with new TypeInfo Reflection API, used in new .NET environments like Windows Phone 8.1 and Apps for Windows Store and their respective PCL profiles. --- ObjectExtensions.cs | 57 +++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/ObjectExtensions.cs b/ObjectExtensions.cs index 02ea1cc..7c8354d 100644 --- a/ObjectExtensions.cs +++ b/ObjectExtensions.cs @@ -6,12 +6,12 @@ namespace System { public static class ObjectExtensions { - private static readonly MethodInfo CloneMethod = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance); + private static readonly MethodInfo CloneMethod = typeof(Object).GetTypeInfo().GetDeclaredMethod("MemberwiseClone"); - public static bool IsPrimitive(this Type type) + public static bool IsValue(this Type type) { if (type == typeof(String)) return true; - return (type.IsValueType & type.IsPrimitive); + return type.GetTypeInfo().IsValueType; } public static Object Copy(this Object originalObject) @@ -22,14 +22,14 @@ private static Object InternalCopy(Object originalObject, IDictionary array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices)); @@ -37,31 +37,52 @@ private static Object InternalCopy(Object originalObject, IDictionary !info.IsStatic && !info.FieldType.GetTypeInfo().IsPrimitive); + CopyProperties(originalObject, visited, cloneObject, typeToReflect, info => !info.GetMethod.IsStatic && !info.PropertyType.GetTypeInfo().IsPrimitive); + RecursiveCopyBaseTypeFields(originalObject, visited, cloneObject, typeToReflect); return cloneObject; } - private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect) + private static void RecursiveCopyBaseTypeFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect) { - if (typeToReflect.BaseType != null) + if (typeToReflect.GetTypeInfo().BaseType != null) { - RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType); - CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | BindingFlags.NonPublic, info => info.IsPrivate); + RecursiveCopyBaseTypeFields(originalObject, visited, cloneObject, typeToReflect.GetTypeInfo().BaseType); + CopyFields(originalObject, visited, cloneObject, typeToReflect.GetTypeInfo().BaseType, info => !info.IsStatic && !info.FieldType.GetTypeInfo().IsPrimitive); + CopyProperties(originalObject, visited, cloneObject, typeToReflect.GetTypeInfo().BaseType, info => !info.GetMethod.IsStatic && !info.PropertyType.GetTypeInfo().IsPrimitive); } } - private static void CopyFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy, Func filter = null) + private static void CopyFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect, Predicate filter = null) { - foreach (FieldInfo fieldInfo in typeToReflect.GetFields(bindingFlags)) + List filtered = new List(typeToReflect.GetTypeInfo().DeclaredFields); + if (filter != null) + { + filtered = filtered.FindAll(filter); + } + foreach (FieldInfo fieldInfo in filtered) { - if (filter != null && filter(fieldInfo) == false) continue; - if (IsPrimitive(fieldInfo.FieldType)) continue; var originalFieldValue = fieldInfo.GetValue(originalObject); var clonedFieldValue = InternalCopy(originalFieldValue, visited); fieldInfo.SetValue(cloneObject, clonedFieldValue); } } + + private static void CopyProperties(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect, Predicate filter = null) + { + List filtered = new List(typeToReflect.GetTypeInfo().DeclaredProperties); + if(filter != null) + { + filtered = filtered.FindAll(filter); + } + foreach (PropertyInfo propertyInfo in filtered) + { + if (IsValue(propertyInfo.PropertyType)) continue; + var originalFieldValue = propertyInfo.GetValue(originalObject); + var clonedFieldValue = InternalCopy(originalFieldValue, visited); + propertyInfo.SetValue(cloneObject, clonedFieldValue); + } + } public static T Copy(this T original) { return (T)Copy((Object)original); @@ -87,7 +108,7 @@ public static class ArrayExtensions { public static void ForEach(this Array array, Action action) { - if (array.LongLength == 0) return; + if (array.Length == 0) return; ArrayTraverse walker = new ArrayTraverse(array); do action(array, walker.Position); while (walker.Step()); @@ -128,4 +149,4 @@ public bool Step() } } -} +} \ No newline at end of file From 0684bfb05e3dbb5985d1a8a416ae7c8d280b52da Mon Sep 17 00:00:00 2001 From: Gameleon12 Date: Thu, 30 Oct 2014 13:47:45 +0100 Subject: [PATCH 2/2] Removed redundant CopyProperties code CopyProperties method has been removed because underlying property values are copied by the CopyField methods. --- ObjectExtensions.cs | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/ObjectExtensions.cs b/ObjectExtensions.cs index 7c8354d..fff1d35 100644 --- a/ObjectExtensions.cs +++ b/ObjectExtensions.cs @@ -38,7 +38,6 @@ private static Object InternalCopy(Object originalObject, IDictionary !info.IsStatic && !info.FieldType.GetTypeInfo().IsPrimitive); - CopyProperties(originalObject, visited, cloneObject, typeToReflect, info => !info.GetMethod.IsStatic && !info.PropertyType.GetTypeInfo().IsPrimitive); RecursiveCopyBaseTypeFields(originalObject, visited, cloneObject, typeToReflect); return cloneObject; } @@ -49,7 +48,6 @@ private static void RecursiveCopyBaseTypeFields(object originalObject, IDictiona { RecursiveCopyBaseTypeFields(originalObject, visited, cloneObject, typeToReflect.GetTypeInfo().BaseType); CopyFields(originalObject, visited, cloneObject, typeToReflect.GetTypeInfo().BaseType, info => !info.IsStatic && !info.FieldType.GetTypeInfo().IsPrimitive); - CopyProperties(originalObject, visited, cloneObject, typeToReflect.GetTypeInfo().BaseType, info => !info.GetMethod.IsStatic && !info.PropertyType.GetTypeInfo().IsPrimitive); } } @@ -67,22 +65,7 @@ private static void CopyFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect, Predicate filter = null) - { - List filtered = new List(typeToReflect.GetTypeInfo().DeclaredProperties); - if(filter != null) - { - filtered = filtered.FindAll(filter); - } - foreach (PropertyInfo propertyInfo in filtered) - { - if (IsValue(propertyInfo.PropertyType)) continue; - var originalFieldValue = propertyInfo.GetValue(originalObject); - var clonedFieldValue = InternalCopy(originalFieldValue, visited); - propertyInfo.SetValue(cloneObject, clonedFieldValue); - } - } + public static T Copy(this T original) { return (T)Copy((Object)original);