zoukankan      html  css  js  c++  java
  • 对象属性赋值后续(集合对象的属性赋值)

    (一)前言

    继《对象属性之间的相互赋值 》后,关于集合对象属性的赋值,主要可以通过循环遍历集合中的对象来进行属性间的赋值。这些可以运用于不同对象之间、相关属性类似的情况。最常见的是web services与silverlight之间的对象赋值(对象之间的属性值只有一部分是需要的),这样可以减少silverlight对web services的依赖。

    (二)具体实现

    通过反射将源对象与目标对象之间的属性赋值。源对象的属性名、属性类型必须与目标对象的属性名、属性类型一致,并且源对象的属性必须是可读的,目标对象的属性是可写的(仅针对于需要赋值的属性来说)。具体的源代码如下:

     1     public class ObjectMapper  
     2     {
     3         private static readonly Dictionary<string, IList<PropertyMapper>> _mappers =
     4             new Dictionary<string, IList<PropertyMapper>>();
     5 
     6         public static IList<PropertyMapper> GetMapperProperties(
     7             Type sourceType, Type targetType)
     8         {
     9             var sourceProperties = sourceType.GetProperties();
    10             var targetProperties = targetType.GetProperties();
    11 
    12             return (from s in sourceProperties
    13                     from t in targetProperties
    14                     where s.Name == t.Name && s.CanRead && t.CanWrite && s.PropertyType == t.PropertyType
    15                     select new PropertyMapper
    16                               {
    17                                   SourceProperty = s,
    18                                   TargetProperty = t
    19                               }).ToList();
    20         }
    21 
    22         public static void CopyProperties<T1, T2>(List<T1> sources, List<T2> targets) where T2:new()
    23         {
    24             if (sources == null || sources.Count == 0 || targets == null)
    25             {
    26                 return;
    27             }
    28 
    29             T2 target;
    30             foreach (T1 source in sources)
    31             {
    32                 target = new T2();
    33                 CopyProperties(source, target);
    34                 targets.Add(target);
    35             }
    36         }
    37 
    38         public static void CopyProperties(object source, object target)
    39         {
    40             if (source == null || target == null)
    41             {
    42                 return;
    43             }
    44             var sourceType = source.GetType();
    45             var targetType = target.GetType();
    46             string key = GetMapperKey(sourceType, targetType);
    47             if (!_mappers.ContainsKey(key))
    48             {
    49                 MapperProperties(sourceType, targetType);
    50             }
    51 
    52             var mapperProperties = _mappers[key];
    53 
    54             SetPropertityValue(source, target, mapperProperties);
    55         }
    56 
    57         private static void SetPropertityValue(object source, 
    58             object target, IList<PropertyMapper> mapperProperties)
    59         {
    60             for (int index = 0, count = mapperProperties.Count; index < count; index++)
    61             {
    62                 var property = mapperProperties[index];
    63                 var sourceValue = property.SourceProperty.GetValue(source, null);
    64                 property.TargetProperty.SetValue(target, sourceValue, null);
    65             }
    66         }
    67 
    68         protected static string GetMapperKey(Type sourceType, Type targetType)
    69         {
    70             return string.Format("{0}_{1}", sourceType.FullName,
    71                 targetType.FullName);
    72         }
    73 
    74         public static void MapperProperties(Type source, Type target)
    75         {
    76             if (source == null || target == null)
    77             {
    78                 return;
    79             }
    80 
    81             string key = GetMapperKey(source, target);
    82             if (_mappers.ContainsKey(key))
    83             {
    84                 return;
    85             }
    86 
    87             var properties = GetMapperProperties(source, target);
    88             _mappers.Add(key, properties);
    89         }
    90     }

    有效的方法主要为如下2个:

    (1)第22-36行CopyProperties<T1, T2>(List<T1> sources, List<T2> targets) where T2:new()

    目标对象集合必须添加约束(where T2:new())---必须有默认构造函数。从如下的代码可以看出 target = new T2()必须通过实例化,才能将其添加到目标集合中。

                    T2 target;
    30             foreach (T1 source in sources)
    31             {
    32                 target = new T2();
    33                 CopyProperties(source, target);
    34                 targets.Add(target);
    35             }

    (2)CopyProperties(object source, object target)
    这个方法才是最关键的,因为集合对象之间的赋值主要是通过循环该方法来赋值的。

     

    (三)单元测试

    对象集合对象之间的赋值,相关的单元测试代码如下(仅考虑了简单的对象),通过下面的测试,可以检测到集合对象属性赋值赋值后,值是相同的:

     1         [TestMethod()]
     2         public void CopyPropertiesTest1()
     3         {
     4             List<Jasen.Core.Info> sources = new List<Core.Info>();
     5             for (int index = 0; index < 10; index++)
     6             {
     7                 sources.Add(new Jasen.Core.Info()
     8                 {
     9                     Name = "jasen",
    10                     CreateTime = "2011-5-13".AsDateTime(),
    11                     Exist = true,
    12                     ConflictOption = ConflictOption.OverwriteChanges,
    13                     Index = index
    14                 });
    15             }
    16             List<Info> targets = new List<Info>();    
    17             ObjectMapper.CopyProperties(sources, targets);
    18             for (int index = 0, count = sources.Count; index < count; index++)
    19             {
    20                 Assert.AreEqual(sources[index].ConflictOption, targets[index].ConflictOption);
    21                 Assert.AreEqual(sources[index].CreateTime, targets[index].CreateTime);
    22                 Assert.AreEqual(sources[index].Exist, targets[index].Exist);
    23                 Assert.AreEqual(sources[index].Name, targets[index].Name);
    24                 //Assert.AreEqual(sources[index].Index, targets[index].Index);
    25             }
    26         }

    (四)总结

    以上的代码仅仅针对于简单的属性之间的赋值,对于对象包含IList集合属性的赋值,可以将该IList再进行一次赋值即可。上文中采用字典来使性能提高,当第一次赋值的时候保存需要赋值的相关联的属性对集合。第二次的时候就直接通过键值获取该属性对,不需要再次查找相关的属性对集合。

     

    源代码下载:Jasen.CopyObjectToObjectSample.rar

     

  • 相关阅读:
    删除某个目录下面指定名字的文件夹的命令
    ubuntu 12.04 下面安装vmware workstation 8.0.4
    最近一段时间总结
    ejb 学习笔记HelloWorld入门实例
    状态会话bean的session周期与Web上的session周期
    ubuntu做路由器
    Heron and His Triangle 递推 高精度 打表 HDU6222
    洛谷训练赛 A.Misaka Network
    HZNU Training 1 for Zhejiang Provincial Competition 2020 Xeon第三场训练赛
    莫比乌斯反演
  • 原文地址:https://www.cnblogs.com/jasenkin/p/copy_source_object_propertities_to_target.html
Copyright © 2011-2022 走看看