diff --git a/MLEM.Data/CopyExtensions.cs b/MLEM.Data/CopyExtensions.cs index 8823a80..2ea372f 100644 --- a/MLEM.Data/CopyExtensions.cs +++ b/MLEM.Data/CopyExtensions.cs @@ -7,17 +7,20 @@ namespace MLEM.Data { /// public static class CopyExtensions { + private const BindingFlags DefaultFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + /// /// Creates a shallow copy of the object and returns it. /// Note that, for this to work correctly, needs to contain a parameterless constructor. /// /// The object to create a shallow copy of /// The binding flags for field searching + /// A predicate that determines whether or not the given field should be copied. If null, all fields will be copied. /// The type of the object to copy /// A shallow copy of the object - public static T Copy(this T obj, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) { + public static T Copy(this T obj, BindingFlags flags = DefaultFlags, Predicate fieldInclusion = null) { var copy = (T) Construct(typeof(T), flags); - obj.CopyInto(copy, flags); + obj.CopyInto(copy, flags, fieldInclusion); return copy; } @@ -27,11 +30,12 @@ namespace MLEM.Data { /// /// The object to create a deep copy of /// The binding flags for field searching + /// A predicate that determines whether or not the given field should be copied. If null, all fields will be copied. /// The type of the object to copy /// A deep copy of the object - public static T DeepCopy(this T obj, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) { + public static T DeepCopy(this T obj, BindingFlags flags = DefaultFlags, Predicate fieldInclusion = null) { var copy = (T) Construct(typeof(T), flags); - obj.DeepCopyInto(copy, flags); + obj.DeepCopyInto(copy, flags, fieldInclusion); return copy; } @@ -41,10 +45,13 @@ namespace MLEM.Data { /// The object to create a shallow copy of /// The object to copy into /// The binding flags for field searching + /// A predicate that determines whether or not the given field should be copied. If null, all fields will be copied. /// The type of the object to copy - public static void CopyInto(this T obj, T otherObj, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) { - foreach (var field in typeof(T).GetFields(flags)) - field.SetValue(otherObj, field.GetValue(obj)); + public static void CopyInto(this T obj, T otherObj, BindingFlags flags = DefaultFlags, Predicate fieldInclusion = null) { + foreach (var field in typeof(T).GetFields(flags)) { + if (fieldInclusion == null || fieldInclusion(field)) + field.SetValue(otherObj, field.GetValue(obj)); + } } /// @@ -54,9 +61,12 @@ namespace MLEM.Data { /// The object to create a deep copy of /// The object to copy into /// The binding flags for field searching + /// A predicate that determines whether or not the given field should be copied. If null, all fields will be copied. /// The type of the object to copy - public static void DeepCopyInto(this T obj, T otherObj, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) { + public static void DeepCopyInto(this T obj, T otherObj, BindingFlags flags = DefaultFlags, Predicate fieldInclusion = null) { foreach (var field in obj.GetType().GetFields(flags)) { + if (fieldInclusion != null && !fieldInclusion(field)) + continue; var val = field.GetValue(obj); if (val == null || field.FieldType.IsValueType) { // if we're a value type (struct or primitive) or null, we can just set the value