2012-01-13 89 views
0

說我有兩個集合即列表< PersonOld>和List < PersonNew> as下。使用通用功能將一個集合的內容複製到另一個

private List<PersonOld> GetOldPersonRecord() 
{ 
      var sourceList = new List<PersonOld>(); 
      for (int i = 1; i <= 10; i++) 
       sourceList.Add(new PersonOld { PersonId = i, PersonName = "Name" + i.ToString() }); 
      return sourceList; 
} 

需要的是填充列表< PersonNew>與清單< PersonOld>的值。

它需要是通用的..means給定的任何源收集和目的地的效用函數,它需要從源填充目標集合。

我想

public List<T2> Fill<T1, T2>(List<T1> Source, List<T2> Destination) 
    { 

     Type type1 = typeof(T1); 
     var type1List = type1.GetProperties(); 

     Type type2 = typeof(T2); 
     var type2List = type2.GetProperties(); 


     //determine the underlying type the List<> contains 
     Type elementType = type1.GetGenericArguments()[0]; 
     foreach (object record in Source) 
     { 
      int i = 0; 
      object[] fieldValues = new object[Destination.Count]; 

      foreach (PropertyInfo prop in Destination) 
      { 
       MemberInfo mi = elementType.GetMember(prop.Name)[0]; 
       if (mi.MemberType == MemberTypes.Property) 
       { 
        PropertyInfo pi = mi as PropertyInfo; 
        fieldValues[i] = pi.GetValue(record, null); 
       } 
       else if (mi.MemberType == MemberTypes.Field) 
       { 
        FieldInfo fi = mi as FieldInfo; 
        fieldValues[i] = fi.GetValue(record); 
       } 
       i++; 
      } 
      //Destination..Add(fieldValues); 
     }   
    } 

和調用

var source = GetOldPersonRecord(); 
var result = Utility.Fill(source, new List<PersonNew>()); 

但沒有luck..please幫助

的實體是爲下

PersonNew

public class PersonNew 
{ 
     public int PersonId { get; set; } 
     public string PersonName { get; set; } 
} 

PersonOld

public class PersonOld 
{ 
     public int PersonId { get; set; } 
     public string PersonName { get; set; } 
} 

我可能要使用反射...

在此先感謝

+0

是使用 「動態」 的一個可行的選擇? – 2012-01-13 08:25:08

回答

1

下面是一個工作示例:

主片是CreateMapping方法,它只是提供了一個委託從一種類型轉換爲另一種。一旦你有了,將源對象複製到目標對象列表中就變得微不足道了,如下面的填充方法所示。

public static Func<T1, T2> CreateMapping<T1, T2>() 
     where T2 : new() 
    { 
     var typeOfSource = typeof(T1); 
     var typeOfDestination = typeof(T2); 

     // use reflection to get a list of the properties on the source and destination types 
     var sourceProperties = typeOfSource.GetProperties(); 
     var destinationProperties = typeOfDestination.GetProperties(); 

     // join the source properties with the destination properties based on name 
     var properties = from sourceProperty in sourceProperties 
         join destinationProperty in destinationProperties 
         on sourceProperty.Name equals destinationProperty.Name 
         select new { SourceProperty = sourceProperty, DestinationProperty = destinationProperty }; 

     return (x) => 
     { 
      var y = new T2(); 

      foreach (var property in properties) 
      { 
       var value = property.SourceProperty.GetValue(x, null); 
       property.DestinationProperty.SetValue(y, value, null); 
      } 

      return y; 
     }; 
    } 

    public static void Fill<T1, T2>(List<T1> Source, List<T2> Destination) 
     where T2 : new() 
    { 
     Destination.AddRange(Source.Select(CreateMapping<T1, T2>())); 
    } 
1

你可以看看AutoMapper


至於你的工具方法而言必須聲明泛型參數:

public class Utility 
{ 
    public static List<T2> Fill<T1, T2>(List<T1> Source, List<T2> Destination) 
    { 
     return null; 
    } 
} 
+0

要求TeamCity用戶名和密碼 – user1025901 2012-01-13 07:05:46

+0

@ user1025901,你可以通過NuGet包安裝它:'Install-Package AutoMapper'或者從GitHub下載:https://github.com/AutoMapper/AutoMapper/downloads – 2012-01-13 07:06:34

+0

這很好...如果我想通過自己編程做,可以請您給的初步指導...效用函數的聲明是給一些問題 – user1025901 2012-01-13 07:10:57

0

如果使用反射,遍歷源集合,實例化目標類的實例。將這些插入到新創建的列表中。

接下來,使用源類型的GetProperties獲取PropertyInfo類的集合。遍歷這些,挑出每個的名稱,並使用Type.GetProperty查看目標類上是否有相同名稱的屬性。如果是這樣,請使用PropertyInfo.SetValue設置每個目標對象上的值。

NB需要做一些更多的工作,如果屬性是引用類型 - 你需要考慮你是否要複製這些類型,或複製參考

如果對象是相同的,另一種做法要連接XML和XML。

+0

嘗試這樣的公開名單填寫(名單源,列表目的地) { 類型type1 = typeof(T1); var type1List = type1.GetProperties(); 類型type2 = typeof(T2); var type2List = type2.GetProperties(); foreach(PropertyInfo prop in type1List) { var name = prop.Name; } } ..你能請幫忙 – user1025901 2012-01-13 07:34:46

+0

嗨,我已經更新了我的答案..但是我還沒有達到解決方案..請你幫忙一下.. – user1025901 2012-01-13 07:56:11

+0

看起來你現在有一個上面的好例子。祝你好運! – ClimberG 2012-01-13 08:49:07

相關問題