2014-02-27 43 views
0

我正在使用此方法将一个对象的属性复制到另一个对象,并且它的工作正常。 但今天我发现它不适用于不同对象的数组。将对象属性复制到另一个

请在这帮助我。

public static class CopyClass 
{ 
    /// <summary> 
    /// Copies source object properties to target object properties. 
    /// </summary> 
    /// <param name="source">The source.</param> 
    /// <param name="target">The target.</param> 
    public static void CopyTo(object source, object target) 
    { 
     foreach (PropertyInfo propSource in source.GetType().GetProperties()) 
     { 
      foreach (PropertyInfo propTarget in target.GetType().GetProperties()) 
      { 
       if (propTarget.Name != propSource.Name) continue; 
       (propTarget.GetSetMethod()).Invoke(target, 
        new object[] { propSource.GetGetMethod().Invoke(source, null) }); 
      } 
     } 
    } 
} 
+5

你可以使用AutoMapper http://automapper.org/ – jjchiw

+0

你的对象序列化? – binard

回答

0

你能检查这个功能吗?我不确定这是否与阵列合作,但它确实与普通成员有关。

public static object ObjectCopyProperties(this object sourceObject, object targetObject) 
    { 
     if (sourceObject == null || targetObject == null) 
      return null; 

     var targetInstance = targetObject; 
     PropertyInfo newProp; 
     foreach (PropertyInfo prop in sourceObject.GetType().GetProperties()) 
     { 
      if (prop.CanRead) 
      { 
       newProp = targetInstance.GetType().GetProperty(prop.Name); 
       if (newProp != null && newProp.CanWrite) 
       { 
        newProp.SetValue(targetInstance, prop.GetValue(sourceObject, null), null); 
       } 
      } 
     } 
     return targetInstance; 
    } 
0

考虑以下2类

public class UserType1 
{ 
    public DateTime Created { get; set; } 
    public string First { get; set; } 
    public Gender Genter { get; set; } 
    public int Id { get; set; } 
    public string Last { get; set; } 
    public DateTime Updated { get; set; } 
    public string DontMatchType { get; set; } 
    public string Unique1 { get; set; } 
} 

public class UserType2 
{ 
    public DateTime Created { get; set; } 
    public string First { get; set; } 
    public Gender Genter { get; set; } 
    public int Id { get; set; } 
    public string Last { get; set; } 
    public DateTime Updated { get; set; } 
    public int DontMatchType { get; set; } 
    public string Unique2 { get; set; } 
} 

和下面的代码

UserType1 user1 = new UserType1 
     { 
      Id = 1, 
      First = "John", 
      Last = "Doe", 
      Genter = Gender.Male, 
      Created = DateTime.Now.AddDays(-1), 
      Updated = DateTime.Now, 
      DontMatchType = "won't map", 
      Unique1 = "foobar" 
     }; 
    UserType2 user2 = CopyTo<UserType2>(user1); 

你可以看到这个映射功能将只地图匹配名称/类型

public static T CopyTo<T>(object source) 
    where T : new() 
{ 
    if (source == null) throw new ArgumentException("surce is null", "source"); 
    T target = new T(); 

    source.GetType() 
      .GetProperties() 
      .Join(target.GetType().GetProperties() 
       , s => s.Name 
       , t => t.Name 
       , (s, t) => new 
        { 
         source = s, 
         target = t 
        }) 
      .AsParallel() 
      .Where(inCommon => inCommon.source.PropertyType == inCommon.target.PropertyType 
          && inCommon.source.CanRead && inCommon.target.CanWrite) 
      .ForAll(inCommon => inCommon.target.SetValue(target, inCommon.source.GetValue(source, null), null)); 
    return target; 
} 

,你可以使用

public static IEnumerable<T> CopyTo<T>(IEnumerable<object> source) 
    where T : new() 
{ 
    return source.AsParallel().Select(CopyTo<T>); 
} 

复制收集这样

UserType1[] users1 = new[] 
     { 
      new UserType1 
       { 
        ... 
       } 
     }; 
    UserType2[] users2 = CopyTo<UserType2>(users1).ToArray(); 

这样做,它不会无谓地循环对象B为对象的每个属性的所有属性,其使用连接到额外的好处找到共同的属性(按名称和类型)。

映射可能会非常棘手。你可以进入很多名称/类型和嵌套的情况。我建议Automapper作为jjchiw提到。

0

如果你的对象是序列化,你可以创建一个序列化的源对象,并在返回反序列化的扩展方法

public static class CloneExtensions 
{ 
    public static T Clone<T>(this T source) 
    { 
     if (!typeof(T).IsSerializable) 
     { 
      throw new ArgumentException("The type must be serializable.", "source"); 
     } 

     if(source == default(T)) 
      return default(T); 

     IFormatter formatter = new BinaryFormatter(); 
     Stream stream = new MemoryStream(); 
     using (stream) 
     { 
      formatter.Serialize(stream, source); 
      stream.Seek(0, SeekOrigin.Begin); 
      return (T)formatter.Deserialize(stream); 
     } 
    } 
} 
相关问题