如何转换ListList< B>

本文关键字:List 何转换 转换 | 更新日期: 2023-09-27 18:15:33

如何将List<SelectVacancyDetails_Result>转换为List< SelectVacancyDetails_ResultExtend>其中SelectVacancyDetails_ResultExtend类继承自SelectVacancyDetails_Result类。

我在下面试过,但是没有运气

   List<SelectVacancyDetails_ResultExtend> vacExtList = vacList.Cast<SelectVacancyDetails_ResultExtend>().ToList();

(基本上我想所有的列表属性值复制过来)

如何转换List<A>List< B>

如果所有元素实际上是SelectVacancyDetails_Result(而不是SelectVacancyDetails_ResultExtend)类型的,那么您不能只是强制转换。最简单的方法是在SelectVacancyDetails_ResultExtend中创建一个复制属性的构造函数——或者可能只是使用组合而不是继承——然后可以使用:

var vacExtList = vacList.Select(vac => new SelectVacancyDetails_ResultExtend(vac))
                        .ToList();

继承不是这样工作的。使用class Derived : Base,不可能将运行时类型为Base的对象"强制转换"为Derived。您需要手动复制所有属性,或者使用类似于AutoMapper的东西。

List<SelectVacancyDetails_ResultExtend> vacExtList = vacList.Select(x => (SelectVacancyDetails_ResultExtend)x).ToList();

你不能这样做,如果你说:

SelectVacancyDetails_ResultExtend继承SelectVacancyDetails_Result

则不能将类型为SelectVacancyDetails_Result的对象强制转换为类型为SelectVacancyDetails_ResultExtend的对象

可以将SelectVacancyDetails_ResultExtend类型转换为SelectVacancyDetails_Result类型,但不能反过来。

您需要将您的属性投影到基类项列表中:

var vacExtList = vacList.Select(v => new SelectVacancyDetails_ResultExtend() {
   PropertyA = v.PropertyA,
   ...
});

我还需要注意的是,需要这样做是有点代码气味-你的继承链有问题。

如果堆栈项的解决方案不起作用,可能是因为其中一个项无法强制转换。(可能是一个不太具体的类型的实例)

您所能做的只是获取可以强制转换的元素,并使用以下代码:

var vacExtList = vacList.OfType<SelectVacancyDetails_ResultExtend>();

编辑:

此解决方案假设SelectVacancyDetails_ResultExtend继承自SelectVacancyDetails_Result,显然

不可能。但是,您可以尝试以下解决方案:

 class Program
{
    static void Main(string[] args)
    {
        var vacancies = new List<Vacancy>
        {
            new Vacancy {Id = 1, Details = "flat"},
            new Vacancy {Id = 2, Details = "restaurant"}
        };

        List<VacancyExtended> vacanciesExtended = vacancies.Select(p => new VacancyExtended(p)).ToList();

        foreach (var v in vacanciesExtended)
        {
            Console.WriteLine(v.Details);
        }
        Console.ReadKey();
    }
}

public class Vacancy
{
    public int Id { get; set; }
    public string Details { get; set; }
    public Vacancy(){ }
    public Vacancy(Vacancy vacancy)
    {
        Id = vacancy.Id;
        Details = vacancy.Details;
    }
}
public class VacancyExtended : Vacancy
{
    public VacancyExtended(Vacancy vacancy) : base(vacancy)
    {
    }
    public string AdditionalInfo { get; set; }
}

这是个典型的问题。其他然后使用构造函数在你的派生类或第三方库,如AutoMapper,你也可以用Reflection创建你的自定义扩展方法,它会慢得多,所以不要使用它,如果你在某种瓶颈的工作和使用它,只有当性能不是你不真正担心的东西,或者如果你不能修改你的派生类,由于某种原因不想使用AutoMapper。这些例子只涵盖了带有属性(没有字段)的典型EF模型。

方法是:

public static class Helper
{
    public static IEnumerable<T2> ConvertRange<T1, T2>(this IEnumerable<T1> collection)
        where T1 : class
        where T2 : class, new()
    {
        List<T2> elements = new List<T2>();
        PropertyInfo[] propsT2 = typeof(T2).GetProperties();
        PropertyInfo[] propsT1 = typeof(T1).GetProperties()
            .Where(p => propsT2.Any(p2 => p2.Name == p.Name)).ToArray();
        propsT1.OrderBy(p => p.Name);
        propsT2.OrderBy(p => p.Name);
        foreach (T1 item in collection)
        {
            T2 newEl = new T2();
            for (int i = 0; i < propsT1.Length; i++)
                propsT2[i].SetValue(newEl, propsT1[i].GetValue(item));
            elements.Add(newEl);
        }
        return elements;
    }
}

的例子:

    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    class Manager
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    static void Main(string[] args)
    {
        List<Person> ps = new List<Person>()
        {
            new Person() { Name ="Alex", Age = 30 },
            new Person() { Name ="Michael", Age = 22 }
        };
        List<Manager> mgr = ps.ConvertRange<Person, Manager>().ToList();
        foreach (var item in mgr)
            Console.WriteLine(item.Name + "   " + item.Age);
        Console.ReadKey();
   }

}

输出:

Alex     30
Michael  22

下面是使用AutoMapper

的示例
private static void Main(string[] args)
{
    Mapper.CreateMap<Foo, FooBar>();
    List<Foo> randomFoos = new List<Foo>();
    for (int i = 0; i < 10; i++)
    {
        randomFoos.Add(new Foo());
    }
    Console.WriteLine("### Random foos");
    randomFoos.ForEach(Console.WriteLine);
    Console.WriteLine("### Converted foos");
    Mapper.Map<List<FooBar>>(randomFoos)
            .ForEach(Console.WriteLine);
}
public class Foo
{
    public Foo()
    {
        this.Id = Guid.NewGuid().ToString();
        this.Name = Guid.NewGuid().ToString("n")
                        .Substring(6);
    }
    public string Id { get; set; }
    public string Name { get; set; }
    public override string ToString()
    {
        StringBuilder builder = new StringBuilder();
        this.GetType()
            .GetProperties()
            .ToList()
            .ForEach(property => builder.AppendLine(string.Format("{0}: {1}", property.Name, property.GetValue(this))));
        builder.AppendLine();
        return builder.ToString();
    }
}
public class FooBar : Foo
{
    public FooBar()
    {
        this.Description = Guid.NewGuid().ToString()
                                .Substring(12);
    }
    public string Description { get; set; }
}
相关文章: