using System.Dynamic; using System.Reflection; namespace adas_core.Domain.Utils; public static class Mapper // We can only use reference types where T : class { private static readonly Dictionary PropertyMap; static Mapper() { // At this point we can convert each // property name to lower case so we avoid // creating a new string more than once. PropertyMap = typeof(T) .GetProperties() .ToDictionary( p => p.Name.ToLower(), p => p ); } public static void Map(ExpandoObject source, T destination) { // Might as well take care of null references early. if (source == null) throw new ArgumentNullException(nameof(source)); if (destination == null) throw new ArgumentNullException(nameof(destination)); // By iterating the KeyValuePair of // source we can avoid manually searching the keys of // source as we see in your original code. foreach (var kv in source) if (PropertyMap.TryGetValue(kv.Key.ToLower(), out var p)) { var propType = p.PropertyType; if (kv.Value == null) { if (propType is { IsByRef: false } && propType.Name != "Nullable`1") // Throw if type is a value type // but not Nullable<> throw new ArgumentException("not nullable"); } else if (kv.Value.GetType() != propType) { // You could make this a bit less strict // but I don't recommend it. p.SetValue(destination, Convert.ToDouble(kv.Value), null); } p.SetValue(destination, kv.Value, null); } } }