如何投射列表<a> to List<b>

时间:2015-10-02 08:39:32

标签: c# asp.net linq

How do I cast List<SelectVacancyDetails_Result> to List< SelectVacancyDetails_ResultExtend> where class SelectVacancyDetails_ResultExtend is inherited from class SelectVacancyDetails_Result.

I tried below but no luck

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

(Basically i want all list properties value to be copied over)

8 个答案:

答案 0 :(得分:7)

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

SelectVacancyDetails_ResultExtend

答案 1 :(得分:1)

继承不起作用。使用class Derived : Base时,无法&#34;施放&#34; runtime type BaseDerived的对象。您需要手动复制所有属性或使用AutoMapper之类的内容。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

如果您已说明:

,则无法执行此操作

SelectVacancyDetails_ResultExtend继承SelectVacancyDetails_Result

然后,您无法转换SelectVacancyDetails_Result类型的对象来输入SelectVacancyDetails_ResultExtend

您可以将SelectVacancyDetails_ResultExtend转换为SelectVacancyDetails_Result,但不能转换为其他方式。

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

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

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

答案 4 :(得分:0)

如果堆栈项目的解决方案不起作用,那么它很可能是因为其中一个项目无法投放。 (也许这是一个不太具体的类型的实例)

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

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

修改

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

答案 5 :(得分:0)

这是不可能的。但是你可以尝试这个解决方案:

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

答案 6 :(得分:0)

这是一个典型的问题。然后在您的派生类或第三方库(如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

答案 7 :(得分:0)

以下是使用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; }
}