2012-01-13 28 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

相关问题