用Reflection 或 AutoMapper 對應兩個Class欄位的值
假設今天有兩個類別 OldClass 與 NewClass
這兩個類別有差不多的欄位
想要將OldClass欄位的值,塞到NewClass欄位該怎麼做比較快呢?
如果欄位不多,最簡單的方法應該就是:
NewClass.xxx = OldClass.xxx <=這樣了吧
但如果欄位有幾十幾百個,那不就key到手軟!?
所以這時候可以用reflection或是利用 automapper 來達成
首先先建立兩個不同的類別,但欄位幾乎一樣
class OldClass
{
public Guid ID { get; set; }
public string Title { get; set; }
public int Price { get; set; }
}
class NewClass
{
public Guid ID { get; set; }
public string Title { get; set; }
public int Price { get; set; }
//比OldClass多一個折扣價格的欄位
public int DiscountPrice { get; set; }
}
接著我用Console程式寫了一個範例
class Program
{
static void Main(string[] args)
{
NewClass n = new NewClass();
//建立物件時直接將值塞入
OldClass o = new OldClass() {
ID = Guid.NewGuid(),
Title = "Reflection",
Price = 350
};
//等等拿來記時用
Stopwatch sw = new Stopwatch();
sw.Reset();
sw.Start();
#region Reflection
//抓出NewClass所有屬性
foreach (var newClassItem in n.GetType().GetProperties())
{
//抓出OldClass所有屬性
foreach (var oldClassItem in o.GetType().GetProperties())
{
//如果屬性一樣的話,就將值塞進NewClass的物件
if (newClassItem.Name == oldClassItem.Name)
{
newClassItem.SetValue(n, oldClassItem.GetValue(o, null)
, null);
break;
}
//對折扣價格另外做判斷及處理
else if (newClassItem.Name == "DiscountPrice" &&
oldClassItem.Name == "Price")
{
newClassItem.SetValue(n,
((int)oldClassItem.GetValue(o, null)) / 2,
null);
break;
}
}
}
#endregion
sw.Stop();
Print(n, sw);
//重設物件
n = null;
sw.Reset();
sw.Start();
#region AutoMapper
//這句話我自己想成定義兩物件要怎麼對應
Mapper.CreateMap<OldClass, NewClass>()
.ForMember(dest => dest.DiscountPrice,
opt => opt.MapFrom(src => src.Price / 2));
//.ForMember可以另外去處理名稱不同的屬性該怎麼對應
//這個例子就是NewClass的DiscountPrice要對應到OldClass的Price除以2
//定義完後就可以對應了
n = Mapper.Map<OldClass, NewClass>(o);
#endregion
sw.Stop();
Print(n,sw);
Console.ReadKey();
}
public static void Print(NewClass n,Stopwatch sw)
{
foreach (var item in n.GetType().GetProperties())
{
Console.WriteLine("屬性名稱:{0},值:{1}",
item.Name,
item.GetValue(n, null));
}
Console.WriteLine("時間:{0}", sw.ElapsedMilliseconds.ToString());
}
}
看看結果:
可以看到兩種方法都可以達到同樣的效果。
參考資料:
我的Coding之路-用Reflection 或 AutoMapper 對應兩個Class欄位的值