【C#】C# 複製 object 物件

C# object 複製

最近有個小情境是:

我在Controller設定了一個Entity Modl的Class (以下稱為BzModel)所有資料。

傳到邏輯層時,先從DB取出Entity(DBModel),之後希望直接將DBModel的每個值轉換為BzModel中的值。

但是,那個Model的Property多達上百個。如果一行一行寫我怕我自己先暈倒吧!

Google出一個Function:

private static T CloneObject<T>(this T sourceObject)
{
   Type t = sourceObject.GetType();
   PropertyInfo[] properties = t.GetProperties();
   Object p = t.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, null, sourceObject, null);
   foreach (PropertyInfo pi in properties)
   {
	   if (pi.CanWrite)
	   {
		   pi.SetValue(p, pi.GetValue(sourceObject, null), null);
	   }
   }
   return (T)Convert.ChangeType(p, typeof(T));
}

印象當時曾直接寫出來,但,已經忘記哪裡寫錯,為何遇到Nullable型別時會發生Exception。

此方法驗證後反倒是沒有這樣的問題。

若想測試,下方程式碼可直接進行測試。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks; 

namespace CloneObject
{

    class Program
    {
        static void Main(string[] args)
        {
            var stu = new Studen()
            {
                Name = "Ming",
                CreateTime = DateTime.Now.AddDays(1),
            }; 

            var stu2 = CloneObject(stu); 

            foreach (var item in stu2.GetType().GetProperties())
            {
                Console.WriteLine(item.Name + ":" + item.GetValue(stu2, null));
            }
        }

        private static T CloneObject<T>(this T sourceObject)
        {
            Type t = sourceObject.GetType();
            PropertyInfo[] properties = t.GetProperties();
            Object p = t.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, null, sourceObject, null);

            foreach (PropertyInfo pi in properties)
            {
                if (pi.CanWrite)
                {
                    pi.SetValue(p, pi.GetValue(sourceObject, null), null);
                }
            }
            return (T)Convert.ChangeType(p, typeof(T));
        }
    }

    public class Studen
    {
        public string Name { get; set; }
        public int? Age { get; set; }
        public DateTime CreateTime { get; set; }
        public DateTime? UpdateTime { get; set; }
    }
}