使用通用函数将一个集合的内容复制到另一个集合

时间:2012-01-13 06:57:43

标签: c# generics

假设我有两个集合,即列表< PersonOld>和列表< PersonNew>如下。

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;
}

需要填写List&lt; PersonNew&gt;使用List&lt; PersonOld&gt;的值。

它需要是通用的..如果给出了实用程序函数的任何源集合和目标,它需要从源填充目标集合。

我正在尝试

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>());

但没有运气......请帮忙

实体在

之下

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; }
}

我可能不得不使用反射...

提前致谢

3 个答案:

答案 0 :(得分:1)

您可以查看AutoMapper


就您的实用程序方法而言,您必须声明泛型参数:

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

答案 1 :(得分: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>()));
    }

答案 2 :(得分:0)

如果使用反射,则遍历源集合,实例化目标类的实例。将这些插入到新创建的列表中。

接下来,在源类型上使用GetProperties来获取PropertyInfo类的集合。迭代这些,选择每个的名称,并使用Type.GetProperty查看目标类上是否存在同名属性。如果是这样,请使用PropertyInfo.SetValue在每个目标对象上设置值。

NB如果属性是引用类型,则需要做更多工作 - 您需要考虑是否要复制这些类型,或复制引用

如果对象相同,则可以选择与XML串行化。