From 7a43d385f5f45b8c6928336f815dbf82f7a7113a Mon Sep 17 00:00:00 2001 From: Kumar Date: Tue, 9 Dec 2025 22:16:47 +0530 Subject: [PATCH] upgrade the map method logic, added case-insenstive match and nullable to non-nullable assign --- AutoMapper.cs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/AutoMapper.cs b/AutoMapper.cs index 6d82251..4f50e0a 100644 --- a/AutoMapper.cs +++ b/AutoMapper.cs @@ -5,12 +5,70 @@ namespace AutoMapper { public class AutoMapper { - public void Map(object source, object target) + public static TTarget Map(TSource source) + where TTarget : new() { - if (source == null) throw new ArgumentNullException(nameof(source)); - if (target == null) throw new ArgumentNullException(nameof(target)); + if (source == null) return default!; + TTarget target = new TTarget(); + var sourceProps = typeof(TSource).GetProperties(); + var targetProps = typeof(TTarget).GetProperties(); + + foreach (var tProp in targetProps) + { + if (!tProp.CanWrite) continue; + + // Case-insensitive match + var sProp = sourceProps.FirstOrDefault( + sp => string.Equals(sp.Name, tProp.Name, StringComparison.OrdinalIgnoreCase) + ); + + if (sProp == null) continue; + + var sValue = sProp.GetValue(source); + + if (sValue == null) + { + // If nullable → non-nullable, assign default value ("" for string) + if (!IsNullable(tProp.PropertyType)) + { + tProp.SetValue(target, GetDefaultValue(tProp.PropertyType)); + } + continue; + } + + // Type matches → direct assign + if (tProp.PropertyType == sProp.PropertyType) + { + tProp.SetValue(target, sValue); + continue; + } + + // Try convert types (string ↔ int, etc.) + try + { + var converted = Convert.ChangeType(sValue, tProp.PropertyType); + tProp.SetValue(target, converted); + } + catch + { + // ignore conversion errors + } + } + + return target; + } + + private static bool IsNullable(Type t) + { + return !t.IsValueType || Nullable.GetUnderlyingType(t) != null; + } + + private static object GetDefaultValue(Type t) + { + if (t == typeof(string)) return string.Empty; + return Activator.CreateInstance(t)!; } } }