大量のプロパティを持つオブジェクト間でプロパティの値をコピーしたいことがあります。
毎回コピーするコードを書くのも面倒なので、メモをしておきます。
昨日のコードは型が異なる場合に使えなかったので、雑に型変換処理を入れてみました。
下記コードの PropertyCopier クラスの CopyTo メソッドでコピーできます。
public static class PropertyCopier { public static T CopyTo<T>(object src, T dest) { var it = typeof(int); if (src == null || dest == null) return dest; var srcProperties = src.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite); var destProperties = dest.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite); var properties = srcProperties.Join(destProperties, p => p.Name, p => p.Name, (p1, p2) => new { p1, p2 }); foreach (var property in properties) { if (property.p1.PropertyType == property.p2.PropertyType) { property.p2.SetValue(dest, property.p1.GetValue(src)); } else { var f = (property.p2.PropertyType == typeof(string)) ? v => Convert.ToString(v) : (property.p2.PropertyType == typeof(short)) ? v => Convert.ToInt16(v) : (property.p2.PropertyType == typeof(short?)) ? v => Convert.ToInt16(v) : (property.p2.PropertyType == typeof(bool)) ? v => Convert.ToBoolean(v) : (property.p2.PropertyType == typeof(bool?)) ? v => Convert.ToBoolean(v) : (property.p2.PropertyType == typeof(int)) ? v => Convert.ToInt32(v) : (property.p2.PropertyType == typeof(int?)) ? v => Convert.ToInt32(v) : (property.p2.PropertyType == typeof(long)) ? v => Convert.ToInt64(v) : (property.p2.PropertyType == typeof(long?)) ? v => Convert.ToInt64(v) : (property.p2.PropertyType == typeof(double)) ? v => Convert.ToDouble(v) : (property.p2.PropertyType == typeof(double?)) ? v => Convert.ToDouble(v) : (property.p2.PropertyType == typeof(decimal)) ? v => Convert.ToDecimal(v) : (property.p2.PropertyType == typeof(decimal?)) ? v => Convert.ToDecimal(v) : (property.p2.PropertyType == typeof(DateTime)) ? v => Convert.ToDateTime(v) : (property.p2.PropertyType == typeof(DateTime?)) ? v => Convert.ToDateTime(v) : (Func<object, object>)null; try { property.p2.SetValue(dest, f?.Invoke(property.p1.GetValue(src))); } catch { property.p2.SetValue(dest, null); } } } return dest; } } class Program { static void Main(string[] args) { var dest = PropertyCopier.CopyTo(new Test1() { Prop1 = "p1", Prop2 = "p2", Prop3 = "p3" }, new Test2()); Console.WriteLine($"{dest.Prop1}, {dest.Prop2}, {dest.Prop3}"); Console.ReadKey(); } } public class Test1 { public string Prop1 { get; set; } public string Prop2 { get; set; } public string Prop3 { get; set; } } public class Test2 { public string Prop1 { get; set; } public string Prop2 { get; set; } public string Prop3 { get; set; } }