将List 复制到List
给定以下类定义:
public class BaseClass { public string SomeProp1 { get; set; } } public class DerivedClass : BaseClass { public string SomeProp2 { get; set; } }
如何获取List
并将其转换为List
?
在我的真实场景中, BaseClass
有一大堆属性,我不想一个一个地复制(然后记得在添加其他属性时保持维护)。
将参数化构造函数添加到BaseClass
不是一个选项,因为此类由WCF服务引用定义。
List result = listBaseClass.ConvertAll(instance => (DerivedClass)instance);
实际上当你需要根据原始对象创建新对象时,ConvertAll是好的,当你需要施放时你可以使用以下
List result = listBaseClass.Cast ().ToList();
如果不是列表中的所有项目都可以转换为DerivedClass,则使用OfType
List result = listBaseClass.OfType ().ToList();
您无法转换实际对象,但可以轻松创建包含已转换内容的新列表:
List baseList = new List (...); // Fill it here... List derivedList = baseList.ConvertAll(b => (DerivedClass) b);
或者,如果您不使用C#3:
List derivedList = baseList.ConvertAll (delegate (BaseClass b) { return (DerivedClass) b; };
这假设原始列表实际上充满了DerivedClass的实例。 如果不是这种情况,请更改委托以基于给定的BaseClass创建适当的DerivedClass实例。
编辑:我不知道为什么我不发布LINQ解决方案:
List derivedList = baseList.Cast ().ToList();
(从这里重复)
首先 – 请注意,您可以向WCF类添加构造函数(和其他代码) – 您只需要在部分类中执行它(并保留生成的代码)。
听起来像列表中的项目类型需要更改 – 所以我们不能只是投射。 反思是一种选择,但速度很慢。 既然你使用的是3.5,我们也许可以编写一个Expression
来为我们更有效地执行…沿着这些行 ,但也使用第二类:
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; static class Program { class Foo { public int Value { get; set; } public override string ToString() { return Value.ToString(); } } class Bar : Foo {} static void Main() { List foos = new List (); for (int i = 0; i < 10; i++) foos.Add(new Foo { Value = i }); List bars = foos.ConvertAll (Clone); } public static TTo Clone(this TFrom obj) where TTo : TFrom, new() { return ObjectExtCache.Convert(obj); } static class ObjectExtCache where TTo : TFrom, new() { private static readonly Func converter; static ObjectExtCache() { ParameterExpression param = Expression.Parameter(typeof(TFrom), "in"); var bindings = from prop in typeof(TFrom).GetProperties() where prop.CanRead && prop.CanWrite select (MemberBinding)Expression.Bind(prop, Expression.Property(param, prop)); converter = Expression.Lambda>( Expression.MemberInit( Expression.New(typeof(TTo)), bindings), param).Compile(); } public static TTo Convert(TFrom obj) { return converter(obj); } } }
using System; using System.Collections.Generic; using System.Text; using System.Linq; namespace ConsoleApplication22 { class Program { static void Main(string[] args) { List source = new List (); source.Add(new DerivedClass { Name = "One" }); source.Add(new BaseClass()); source.Add(new DerivedClass { Name = "Three" }); List result = new List (source.OfType ()); result.ForEach(i => Console.WriteLine(i.Name)); Console.ReadLine(); } } public class BaseClass { } public class DerivedClass : BaseClass { public string Name { get; set; } } }
此代码不仅会转换,而且还只包含派生类的实例,并排除任何不是派生类的实例。
正如其他人所建议的那样,如果你有一个List
的实例,你可以使用List
的ConvertAll
方法将它转换为List
。
更一般地说,如果你有任何实现IEnumerable
(没有ConvertAll
方法)的东西,你可以使用Linq的Cast
来做同样的事情:
IEnumerable result = listBaseClass.Cast ();
如果你需要一个List
而不是IEnumerable
,你可以直接调用ToList()
。
正如Jon所说,这是假设listBaseClass
中的所有条目实际上都是DerivedClass
类型。
只是为了记录,如果有一个带参数的构造函数,您需要显式实例化列表中的每个项目。
使用OP示例:
public class BaseClass { public BaseClass (string param1) { Param1 = param1; } public string SomeProp1 { get; set; } public string Param1 { get; private set; } } public class DerivedClass : BaseClass { public DerivedClass (string param1) : base(param1){} public string SomeProp2 { get; set; } }
在这种情况下,代码行应该是这样的:
List result = listBaseClass.ConvertAll(l=> new DerivedClass(l.Param1));