1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-11-26 06:28:35 +01:00

Allow copying to exclude certain fields

This commit is contained in:
Ellpeck 2020-08-01 00:22:29 +02:00
parent 0529e2c921
commit 3a1b73934b

View file

@ -7,17 +7,20 @@ namespace MLEM.Data {
/// </summary>
public static class CopyExtensions {
private const BindingFlags DefaultFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
/// <summary>
/// Creates a shallow copy of the object and returns it.
/// Note that, for this to work correctly, <typeparamref name="T"/> needs to contain a parameterless constructor.
/// </summary>
/// <param name="obj">The object to create a shallow copy of</param>
/// <param name="flags">The binding flags for field searching</param>
/// <param name="fieldInclusion">A predicate that determines whether or not the given field should be copied. If null, all fields will be copied.</param>
/// <typeparam name="T">The type of the object to copy</typeparam>
/// <returns>A shallow copy of the object</returns>
public static T Copy<T>(this T obj, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) {
public static T Copy<T>(this T obj, BindingFlags flags = DefaultFlags, Predicate<FieldInfo> 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 {
/// </summary>
/// <param name="obj">The object to create a deep copy of</param>
/// <param name="flags">The binding flags for field searching</param>
/// <param name="fieldInclusion">A predicate that determines whether or not the given field should be copied. If null, all fields will be copied.</param>
/// <typeparam name="T">The type of the object to copy</typeparam>
/// <returns>A deep copy of the object</returns>
public static T DeepCopy<T>(this T obj, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) {
public static T DeepCopy<T>(this T obj, BindingFlags flags = DefaultFlags, Predicate<FieldInfo> fieldInclusion = null) {
var copy = (T) Construct(typeof(T), flags);
obj.DeepCopyInto(copy, flags);
obj.DeepCopyInto(copy, flags, fieldInclusion);
return copy;
}
@ -41,11 +45,14 @@ namespace MLEM.Data {
/// <param name="obj">The object to create a shallow copy of</param>
/// <param name="otherObj">The object to copy into</param>
/// <param name="flags">The binding flags for field searching</param>
/// <param name="fieldInclusion">A predicate that determines whether or not the given field should be copied. If null, all fields will be copied.</param>
/// <typeparam name="T">The type of the object to copy</typeparam>
public static void CopyInto<T>(this T obj, T otherObj, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) {
foreach (var field in typeof(T).GetFields(flags))
public static void CopyInto<T>(this T obj, T otherObj, BindingFlags flags = DefaultFlags, Predicate<FieldInfo> fieldInclusion = null) {
foreach (var field in typeof(T).GetFields(flags)) {
if (fieldInclusion == null || fieldInclusion(field))
field.SetValue(otherObj, field.GetValue(obj));
}
}
/// <summary>
/// Copies the given object <paramref name="obj"/> into the given object <see cref="otherObj"/> in a deep manner.
@ -54,9 +61,12 @@ namespace MLEM.Data {
/// <param name="obj">The object to create a deep copy of</param>
/// <param name="otherObj">The object to copy into</param>
/// <param name="flags">The binding flags for field searching</param>
/// <param name="fieldInclusion">A predicate that determines whether or not the given field should be copied. If null, all fields will be copied.</param>
/// <typeparam name="T">The type of the object to copy</typeparam>
public static void DeepCopyInto<T>(this T obj, T otherObj, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) {
public static void DeepCopyInto<T>(this T obj, T otherObj, BindingFlags flags = DefaultFlags, Predicate<FieldInfo> 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