对象属性赋值后续(集合对象的属性赋值)

(一)前言

继《对象属性之间的相互赋值 》后,关于集合对象属性的赋值,主要可以通过循环遍历集合中的对象来进行属性间的赋值。这些可以运用于不同对象之间、相关属性类似的情况。最常见的是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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值