どこかで、コードの大部分は値の代入で占められているという話を見た。 たしかに、単純転送みたいなものはかなり多い。.Net MVCで作ってると、とゆーかEntityFramework使ってると、ポコポコおぶじぇ祭りになりがち。View用に専用のモデルとか作ってると、テーブルのオブジェクトの値転送とか発狂しそうになる。
なので、2つのObjectで、同じ名前のプロパティの値をコピーするやつを作ってみた。割と便利。
//使い方 //CopySameNameProperty(コピー元Object,コピー先Object) using System.Reflection; public static void CopySameNameProperty(object from, object to) { //それぞれのタイプを取得 Type fromType = from.GetType(); Type toType = to.GetType(); //メンバーリスト MemberInfo[] fromMembers = fromType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); MemberInfo[] toMembers = toType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); //名称用のリストを用意 List<string> nameList = new List<string>(); foreach (MemberInfo m in toMembers) { //プロパティの場合のみ if (m.MemberType == MemberTypes.Property) { nameList.Add(m.Name); } } //同名プロパティの値をコピー foreach (MemberInfo m in fromMembers) { if (m.MemberType == MemberTypes.Property) { //同名のプパティがあれば転送する if (nameList.Contains(m.Name)) { toType.GetProperty(m.Name).SetValue(to, fromType.GetProperty(m.Name).GetValue(from, null)); } } } }
ただし、ってか当たり前だけど、データ型は合ってないと落ちる。あと、intとかstringあたり以外のオブジェクトだと参照渡しになって、コピー元の値を変えるとコピー先も変わるので一工夫必要かと。。。
ついでに、プロパティを初期化するやつも作ってみた。MVCで作ってると、 新規にモデル作るときに項目がNULLってくるので、初期化があると楽。他にもやり方はあるだろうけども。。。
using System.Reflection; public static void NullValueInit(object targetObj) { //Typeを取得 Type targetType = targetObj.GetType(); //メンバを取得する MemberInfo[] targetMembers = targetType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); foreach (MemberInfo m in targetMembers) { //プロパティの場合のみ if (m.MemberType == MemberTypes.Property) { if (targetType.GetProperty(m.Name).GetValue(targetObj, null) == null) { //Int32の場合は0で初期化 if (targetType.GetProperty(m.Name).PropertyType.Name == "Int32") targetType.GetProperty(m.Name).SetValue(targetObj, 0); //Stringの場合は""で初期化 else if (targetType.GetProperty(m.Name).PropertyType.Name == "String") targetType.GetProperty(m.Name).SetValue(targetObj, ""); } } } }