diff --git a/src/Speckle.Core/Serialisation/SerializationUtilities/ValueConverter.cs b/src/Speckle.Core/Serialisation/SerializationUtilities/ValueConverter.cs index b203a976..e016c866 100644 --- a/src/Speckle.Core/Serialisation/SerializationUtilities/ValueConverter.cs +++ b/src/Speckle.Core/Serialisation/SerializationUtilities/ValueConverter.cs @@ -1,10 +1,11 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics.Contracts; +using Speckle.DoubleNumerics; using System.Drawing; using System.Globalization; using Speckle.Core.Logging; -using Speckle.DoubleNumerics; using Numerics = System.Numerics; namespace Speckle.Core.Serialisation.SerializationUtilities; @@ -157,16 +158,17 @@ public static bool ConvertValue(Type type, object? value, out object? convertedV #endregion } - // Handle List - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) + // Handle List<>, IList<>, and IReadOnlyList<> + if (type.IsGenericType && IsGenericList(type)) { if (value is not List valueList) { return false; } + var targetType = typeof(List<>).MakeGenericType(type.GenericTypeArguments); Type listElementType = type.GenericTypeArguments[0]; - IList ret = (IList)Activator.CreateInstance(type, valueList.Count); + IList ret = (IList)Activator.CreateInstance(targetType, valueList.Count); foreach (object inputListElement in valueList) { if (!ConvertValue(listElementType, inputListElement, out object? convertedListElement)) @@ -311,4 +313,21 @@ public static bool ConvertValue(Type type, object? value, out object? convertedV return false; } + + /// + /// Tests that the given is assignable from a generic type def + /// + /// + /// + [Pure] + private static bool IsGenericList(Type type) + { + if (!type.IsGenericType) + { + return false; + } + + Type typeDef = type.GetGenericTypeDefinition(); + return typeDef == typeof(List<>) || typeDef == typeof(IList<>) || typeDef == typeof(IReadOnlyList<>); + } }