From 75d8a556eb8ca515a5389f50895ebd852021a043 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sun, 1 Nov 2020 15:36:56 +0100 Subject: [PATCH] made CopyExtensions be able to fall back to a generic constructor if none is found --- MLEM.Data/CopyExtensions.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/MLEM.Data/CopyExtensions.cs b/MLEM.Data/CopyExtensions.cs index aa43cd0..ccf7bd4 100644 --- a/MLEM.Data/CopyExtensions.cs +++ b/MLEM.Data/CopyExtensions.cs @@ -12,7 +12,7 @@ namespace MLEM.Data { /// /// Creates a shallow copy of the object and returns it. - /// Note that, for this to work correctly, needs to contain a parameterless constructor or a constructor with the . + /// Object creation occurs using a constructor with the or, if none is present, the first constructor with the correct . /// /// The object to create a shallow copy of /// The binding flags for field searching @@ -27,7 +27,7 @@ namespace MLEM.Data { /// /// Creates a deep copy of the object and returns it. - /// Note that, for this to work correctly, needs to contain a parameterless constructor or a constructor with the . + /// Object creation occurs using a constructor with the or, if none is present, the first constructor with the correct . /// /// The object to create a deep copy of /// The binding flags for field searching @@ -57,7 +57,7 @@ namespace MLEM.Data { /// /// Copies the given object into the given object in a deep manner. - /// Note that, for this to work correctly, each type that should be constructed below the topmost level needs to contanin a parameterless constructor or a constructor with the . + /// Object creation occurs using a constructor with the or, if none is present, the first constructor with the correct . /// /// The object to create a deep copy of /// The object to copy into @@ -85,13 +85,17 @@ namespace MLEM.Data { } private static object Construct(Type t, BindingFlags flags) { + var constructors = t.GetConstructors(flags); // find a contructor with the correct attribute - var constructor = t.GetConstructors(flags).FirstOrDefault(c => c.GetCustomAttribute() != null); - // fall back to a parameterless constructor + var constructor = constructors.FirstOrDefault(c => c.GetCustomAttribute() != null); + // find a parameterless construcotr if (constructor == null) constructor = t.GetConstructor(flags, null, Type.EmptyTypes, null); + // fall back to the first constructor if (constructor == null) - throw new NullReferenceException($"Type {t} does not have a parameterless constructor or a constructor with the CopyConstructorAttribute with the required visibility"); + constructor = constructors.FirstOrDefault(); + if (constructor == null) + throw new NullReferenceException($"Type {t} does not have a constructor with the required visibility"); return constructor.Invoke(new object[constructor.GetParameters().Length]); }