(一)前言 当不同命名空间下的两个类具有相同的属性,并且需要进行相互赋值时,如下图中的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++) (三)单元测试 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>关系了。 |
|