這兩天看一個要離職同事交接的代碼,看到一個淺拷貝的方法感覺挺好,在這裡記錄一下。
一、方法體
是一個靜態方法CopyHelper,包含以下三個部分
1、給PropertyInfo[]類型加個擴展的方法,方便進行查詢是否存在相同類型,相同名稱的字段。
/// <summary>
/// PropertyInfo[]擴展方法,通過名稱獲得屬性
/// </summary>
/// <param name="P"></param>
/// <param name="pro"></param>
/// <returns></returns>
private static PropertyInfo GetPropertyByName(this PropertyInfo[] P,PropertyInfo pro)
{
if (P == null)
throw new NullReferenceException("CopyHelper類中GetPropertyByName()方法參數PropertyInfo[]為Null");
var item = P.ToList().Find(x => x.Name.Equals(pro.Name) &&
(pro.PropertyType.IsSubclassOf(x.PropertyType) || pro.PropertyType.FullName.Equals(x.PropertyType.FullName)));
return item;
}
2、淺拷貝的主體方法,即調用上面的方法基礎上,如果不為空,並且允許寫入的話,則用SetValue方法進行賦值
/// <summary>
/// 淺拷貝
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="vo">原始的VO</param>
/// <param name="viewModel">VM下的vo</param>
/// <returns></returns>
private static T O2M<T>(object vo,T viewModel)
{
//獲取viewmodel的屬性集合
PropertyInfo[] VmPInfos = viewModel.GetType().GetProperties();
//獲取原始vo的屬性集合
PropertyInfo[] VoPInfos = vo.GetType().GetProperties();
for (int i = 0; i < VoPInfos.Length; i++)
{
//從VM中找到和VO中對應的屬性
var pro = VmPInfos.GetPropertyByName(VoPInfos[i]);
//如果不為空,並且可以寫,則進行賦值
if (pro != null && pro.CanWrite)
pro.SetValue(viewModel, VoPInfos[i].GetValue(vo, null), null);
}
return viewModel;
}
private static T O2M<T>(object vo) where T :new ()
{
if (vo == null)
return default(T);
T viewModel = new T();
return O2M<T>(vo, viewModel);
}
3、向外暴露一個擴展Copy方法,運行調用
/// <summary>
/// 將字段名稱一致,類型一致的屬性賦值(用於ViewModel和Vo相互轉化)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="vo"></param>
/// <returns></returns>
/// <remarks>注意此賦值為淺拷貝,Model會重新new()</remarks>
public static T CopyTo<T>(this object vo) where T :new()
{
return O2M<T>(vo);
}
/// <summary>
/// 將字段名稱一致,類型一致的屬性賦值(用於ViewModel和Vo相互轉化)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="vo"></param>
/// <returns></returns>
/// <remarks>注意此賦值為淺拷貝,Model會重新new()</remarks>
public static bool CopyTo<T>(this object vo,T model)where T :new ()
{
if (model == null)
model = new T();
return O2M<T>(vo, model) != null;
}
二、測試
1、新建兩個實體類,HumanVo和StudentVo
public class HumanVo
{
private string _name;
private int _age;
private bool _sex;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public int Age
{
get
{
return _age;
}
set
{
_age = value;
}
}
public bool Sex
{
get
{
return _sex;
}
set
{
_sex = value;
}
}
}
public class StudentVo
{
private string _name;
private int _age;
private bool _sex;
private string _class;
private string _school;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public int Age
{
get
{
return _age;
}
set
{
_age = value;
}
}
public bool Sex
{
get
{
return _sex;
}
set
{
_sex = value;
}
}
public string Class
{
get
{
return _class;
}
set
{
_class = value;
}
}
public string School
{
get
{
return _school;
}
set
{
_school = value;
}
}
}
2、給HumanVo進行賦值
private void AddInfo()
{
HumanVo.Name = "李蕾";
HumanVo.Age = 16;
HumanVo.Sex = true;
}
3、調用CopyTo方法
HumanVo.CopyTo(StudentVo);
4、查看結果
調用方法之前,跟蹤代碼,看兩個VO的值


調用方法後,查看StudentVO的值
