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

(一)前言
继《对象属性之间的相互赋值 》后,关于集合对象属性的赋值,主要可以通过循环遍历集合中的对象来进行属性间的赋值。这些可以运用于不同对象之间、相关属性类似的情况。最常见的是web services与silverlight之间的对象赋值(对象之间的属性值只有一部分是需要的),这样可以减少silverlight对web services的依赖。
(二)具体实现
通过反射将源对象与目标对象之间的属性赋值。源对象的属性名、属性类型必须与目标对象的属性名、属性类型一致,并且源对象的属性必须是可读的,目标对象的属性是可写的(仅针对于需要赋值的属性来说)。具体的源代码如下:
1 public class ObjectMapper 2 { 3 private static readonly Dictionary> _mappers = 4 new Dictionary>(); 5 6 public static IList 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(List sources, List 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 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(List sources, List 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 sources = new List(); 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 targets = new List(); 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
Tags:  对象不支持此属性 给对象数组赋值 对象赋值 php对象赋值 java对象赋值

延伸阅读

最新评论

发表评论