如何转换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();
(基本上我想所有的列表属性值复制过来)
如果所有元素实际上是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; }
}