你的位置:首页 > ASP.net教程

[ASP.net教程]通过属性进行浅拷贝


这两天看一个要离职同事交接的代码,看到一个浅拷贝的方法感觉挺好,在这里记录一下。

一、方法体

  是一个静态方法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的值