zoukankan      html  css  js  c++  java
  • 对象属性之间的相互赋值

    (一)前言

    当不同命名空间下的两个类具有相同的属性,并且需要进行相互赋值时,如下图中的Jasen.Core.Info类的实例与Jasen.Core.Test.Info类的实例需要相互赋值时,按照一般的思路直接赋值就可以了。通常,这种情况在调用Web Service的时候比较常见。当需要转换的类很多时,亦或者需要转换的属性很多时,我们就需要根据一定的规则来对这种场景来进行设计了,谁也不会傻布拉吉的一个一个属性的去给对象赋值。

     

     (二)ObjectMapper 类负责对象之间相对应的属性间的赋值

     1 /// <summary>
     2     /// 
     3     /// </summary>
     4     public class ObjectMapper  
     5     {
     6         /// <summary>
     7         /// 
     8         /// </summary>
     9         /// <param name="sourceType"></param>
    10         /// <param name="targetType"></param>
    11         /// <returns></returns>
    12         public static IList<PropertyMapper> GetMapperProperties(Type sourceType, Type targetType)
    13         {
    14             var sourceProperties = sourceType.GetProperties();
    15             var targetProperties = targetType.GetProperties();
    16 
    17             return (from s in sourceProperties
    18                     from t in targetProperties
    19                     where s.Name == t.Name && s.CanRead && t.CanWrite && s.PropertyType == t.PropertyType
    20                     select new PropertyMapper
    21                               {
    22                                   SourceProperty = s,
    23                                   TargetProperty = t
    24                               }).ToList();
    25         }       
    26 
    27         /// <summary>
    28         /// 
    29         /// </summary>
    30         /// <param name="source"></param>
    31         /// <param name="target"></param>
    32         public static void CopyProperties(object source, object target)
    33         {
    34             var sourceType = source.GetType();
    35             var targetType = target.GetType();
    36             var mapperProperties = GetMapperProperties(sourceType, targetType);
    37 
    38             for (int index = 0,count=mapperProperties.Count; index < count; index++)
    39             {
    40                 var property = mapperProperties[index];
    41                 var sourceValue = property.SourceProperty.GetValue(source, null);
    42                 property.TargetProperty.SetValue(target, sourceValue, null);
    43             }
    44         }
    45     }

    public static void CopyProperties(object source, object target)方法将源对象的属性值赋给目标对象的属性。其中必须满足以下条件:s.Name == t.Name && s.CanRead && t.CanWrite && s.PropertyType == t.PropertyType,也就是两个对象之间赋值的属性名,属性类型必须相同,而且源对象的属性必须可读,目标对象的属性可写。

     

    public static IList<PropertyMapper> GetMapperProperties(Type sourceType, Type targetType)方法通过LINQ将源对象和目标对象相对应的属性对放置在List<PropertyMapper>集合中,每一个PropertyMapper对应一个SourceProperty和TargetProperty。PropertyMapper类如下:

     1 /// <summary>
     2     /// 
     3     /// </summary>
     4     public class PropertyMapper
     5     {
     6         /// <summary>
     7         /// 
     8         /// </summary>
     9         public PropertyInfo SourceProperty
    10         {
    11             get;
    12             set;
    13         }
    14 
    15         /// <summary>
    16         /// 
    17         /// </summary>
    18         public PropertyInfo TargetProperty
    19         {
    20             get;
    21             set;
    22         }
    23     }

    最后循环来遍历List<PropertyMapper>集合,通过反射进行赋值,主要代码如下:

                     for (int index = 0,count=mapperProperties.Count; index < count; index++)
    39             {
    40                 var property = mapperProperties[index];
    41                 var sourceValue = property.SourceProperty.GetValue(source, null);
    42                 property.TargetProperty.SetValue(target, sourceValue, null);
    43             }

     (三)单元测试

     1         [TestMethod()]
     2         public void CopyPropertiesTest()
     3         {
     4             Jasen.Core.Info source = new Jasen.Core.Info()
     5             {
     6                 Name = "jasen",
     7                 CreateTime = "2011-3-31".AsDateTime(),
     8                 Exist = true,
     9                 ConflictOption = ConflictOption.OverwriteChanges
    10             };
    11             Info target = new Info();  
    12             ObjectMapper.CopyProperties(source, target);
    13 
    14             Assert.AreEqual(source.ConflictOption,target.ConflictOption);
    15             Assert.AreEqual(source.CreateTime, target.CreateTime);
    16             Assert.AreEqual(source.Exist, target.Exist);
    17             Assert.AreEqual(source.Name, target.Name);
    18         }

    (四)其他

    当然,当需要转换的对象很多时,可以采用字典Dictionary来提高性能,Dictionary主要用来保存对象对应属性间的List<PropertyMapper>关系,当下次再次调用时候就不需要再次获取对象对应属性间的List<PropertyMapper>关系了。

  • 相关阅读:
    @Autowired和@Resource注解的注入顺序
    八大排序算法(Java实现)+ 自制动画
    一文秒杀三个经典面试求和问题
    这篇文章,或许对还在上学的你,有一些帮助
    得了,一文把前缀和给扒的干干净净了。
    BF,BM,KMP,就这?
    那个贼贵的比特币到底是什么原理?
    小样?别以为你穿了几个马甲就不认得你是二分法!
    面试前必知必会的二分查找及其变种
    Vue.js 官方示例初探
  • 原文地址:https://www.cnblogs.com/jasenkin/p/copy_object_property_value_to_other_object_property.html
Copyright © 2011-2022 走看看