2011-06-15 93 views
0

我一直在寻求通过指定一个基本数据模型来使我的应用程序更具可扩展性,我打算将其作为一个容器,以便发送到另一个应用程序的数据总是正确的结构。简单的方法将对象值复制到另一个类型的对象?

但是我希望将来能够轻松地从XML和数据库等来源加载数据,所以我想知道如何去将一个对象的值复制到基本数据模型对象,其中对象im复制值可能不是相同的结构(所以我主要只是想匹配属性名称)。

这里是我的尝试:

public Dictionary<string, object> ObjectValues(object source) 
    { 
     if(source == null) 
      return null; 

     Dictionary<string, object> properties = new Dictionary<string, object>(); 
     foreach (PropertyInfo propInfo in source.GetType().GetProperties()) 
     { 
      try 
      { 
       object value = propInfo.GetValue(source, null); 
       properties.Add(propInfo.Name, value); 
       if (!value.GetType().IsPrimitive && !value.GetType().IsValueType) 
       { 
        Dictionary<string, object> internalProperties = ProxyValues(value); 
        if (internalProperties != null) 
         foreach (KeyValuePair<string, object> internalProp in internalProperties) 
          properties.Add(String.Format("{0}.{1}", propInfo.Name, internalProp.Key), internalProp.Value); 
       } 
      } 
      catch (TargetParameterCountException) { } 
     } 
     return properties; 
    } 

谢谢, 亚历克斯。

+0

如果数据是重物,数据模型和反射将会起作用。如果您依赖大量简单的数据(如数以万计的字符串或整数),则由于反射,您会注意到性能下降。 – 2011-06-15 01:01:05

+0

如果我正在阅读这个权利你有一个'BasePocoClass',它有一个定义好的结构,并且你想把它转换成'PocoClass1','PocoClass2'和'PocoClassX',它们都有不同的结构? – 2011-06-15 01:02:32

+0

@Marino Simic约50/50,大量复杂类型和大量简单类型。 – 2011-06-15 01:22:59

回答

4

如果我正确理解你的问题,你可能想看看像AutoMapper

您设置配置的几种方法:

Mapper.CreateMap<TypeA, TypeB>().ForMember(dest => dest.PropB, opt => opt.MapFrom(src => src.PropA)); 

这将创建从TypeA到TypeB的映射,其中属性PropA将被复制到PropB。然后,当你想使用的映射:

TypeA a = new TypeA(); 
TypeB b = new TypeB(); 

Mapper.Map(a, b); 

映射配置甚至可以使用自定义的解析器,所以如果你想复制时,你可以做复杂的工作。

还有ValueInjecter,其中一些人更喜欢自动地图

4

尝试使用AutoMapper。它映射不同类型具有匹配属性名称,也有采取表情自定义映射

+0

这是一个很好的做法。 – 2011-06-15 01:06:07

1

你是在正确的轨道上。您可以使用extension methods将基本类型object扩展为merge函数。这种事情写起来比较微不足道。这是一个我用:

/// <summary> 
/// Merges the equivalent properties from the source to this object. 
/// </summary> 
/// <typeparam name="T">Any reference type.</typeparam> 
/// <param name="destination">This object, which receives the values.</param> 
/// <param name="source">The source object that the values are taken from.</param> 
public static void MergeFrom<T>(this object destination, T source) 
{ 
    Type destinationType = destination.GetType(); 
    PropertyInfo[] propertyInfos = source.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); 
    foreach (var propertyInfo in propertyInfos) 
    { 
     PropertyInfo destinationPropertyInfo = destinationType.GetProperty(propertyInfo.Name, BindingFlags.Public | BindingFlags.Instance); 
     if (destinationPropertyInfo != null) 
     { 
      if (destinationPropertyInfo.CanWrite && propertyInfo.CanRead && (destinationPropertyInfo.PropertyType == propertyInfo.PropertyType)) 
      { 
       object o = propertyInfo.GetValue(source, null); 
       destinationPropertyInfo.SetValue(destination, o, null); 
      } 
     } 
    } 
} 

使用它很简单:

obj1.MergeFrom(obj2); 

将从obj2合并类似性质回obj1,用只相当于属性名称和类型。注意缺少异常处理 - 这是故意的,如果它失败了,那么我想知道它而不是处理和吞咽异常。

你也可以把这个概念直接放在Dictionary<string, object>上,或者作为MergeFrom或者LoadFrom,扩展方法给了你相当大的灵活性。

相关问题