2014-02-27 99 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); 
     } 
    } 
} 
相關問題