2009-02-05 41 views
12

给出下面的类定义:复制列表<BaseClass>为List <DerivedClass>

public class BaseClass 
{ 
    public string SomeProp1 { get; set; } 
} 

public class DerivedClass : BaseClass 
{ 
    public string SomeProp2 { get; set; } 
} 

我如何可以采取List<BaseClass>并将其转换为List<DerivedClass>

在我的真实世界场景BaseClass有一大堆属性,我不想一个接一个复制(然后记住要保留是否添加了一个附加属性)。

将参数化构造函数添加到BaseClass不是一个选项,因为此类由WCF服务引用定义。

+0

不WCF在代理代码中生成_partial_类? – 2009-02-05 16:12:23

+0

乍一看,你并没有说DerivedClass只是在基础之上的功能扩展,或者实际上必须是代码示例所建议的不同的数据结构。恕我直言,在第二种情况下,“转换”是没有意义的。 – 2009-02-05 16:17:56

回答

13
List<DerivedClass> result = 
    listBaseClass.ConvertAll(instance => (DerivedClass)instance); 

其实ConvertAll是好的,当你需要在原有基础上,当你只需要投你可以使用下面的

List<DerivedClass> result = 
    listBaseClass.Cast<DerivedClass>().ToList(); 

如果不是所有的项目要在列表中创建新的对象可强制转换为DerivedClass然后用OfType,而不是

List<DerivedClass> result = 
    listBaseClass.OfType<DerivedClass>().ToList(); 
+0

我会后悔让你回到这里,不是吗? ;) – 2009-02-05 15:53:03

15

不能转换实际的对象,但它很容易地创建一个新的列表与转换的内容:

List<BaseClass> baseList = new List<BaseClass>(...); 
// Fill it here... 

List<DerivedClass> derivedList = baseList.ConvertAll(b => (DerivedClass) b); 

或者,如果你不使用C#3:

List<DerivedClass> derivedList = baseList.ConvertAll<DerivedClass>(delegate 
    (BaseClass b) { return (DerivedClass) b; }; 

这会假定原来的名单竟是满DerivedClass的实例。如果不是这种情况,请将委托更改为基于给定的BaseClass创建适当的DerivedClass实例。

编辑:我不知道为什么我不只是发布LINQ的解决方案:

List<DerivedClass> derivedList = baseList.Cast<DerivedClass>().ToList(); 
3

(从here重复)

首先 - 请注意,您可以添加构造函数(和其他代码)添加到WCF类 - 您只需要在部分类中完成(并保留生成的代码)。

听起来像类型的列表中的项目需要更改 - 所以我们不能只是施放。反射是一种选择,但速度很慢。由于使用的是3.5,我们也许可以写一个Expression这样做对我们更有效地沿着... these lines,但使用第二类太:

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<Foo> foos = new List<Foo>(); 
     for (int i = 0; i < 10; i++) foos.Add(new Foo { Value = i }); 

     List<Bar> bars = foos.ConvertAll<Bar>(Clone<Foo, Bar>); 
    } 
    public static TTo Clone<TFrom, TTo>(this TFrom obj) where TTo : TFrom, new() 
    { 
     return ObjectExtCache<TFrom, TTo>.Convert(obj); 
    } 
    static class ObjectExtCache<TFrom, TTo> where TTo : TFrom, new() 
    { 
     private static readonly Func<TFrom, TTo> 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<Func<TFrom, TTo>>(
       Expression.MemberInit(
        Expression.New(typeof(TTo)), bindings), param).Compile(); 
     } 
     public static TTo Convert(TFrom obj) 
     { 
      return converter(obj); 
     } 
    } 
} 
2
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Linq; 

namespace ConsoleApplication22 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<BaseClass> source = new List<BaseClass>(); 
      source.Add(new DerivedClass { Name = "One" }); 
      source.Add(new BaseClass()); 
      source.Add(new DerivedClass { Name = "Three" }); 

      List<DerivedClass> result = 
       new List<DerivedClass>(source.OfType<DerivedClass>()); 
      result.ForEach(i => Console.WriteLine(i.Name)); 
      Console.ReadLine(); 
     } 
    } 

    public class BaseClass 
    { 
    } 

    public class DerivedClass : BaseClass 
    { 
     public string Name { get; set; } 
    } 

} 

此代码不仅会转换,但也只包含派生类的实例并排除任何不是的派生类。

2

正如其他人所建议的,如果你有一个List<BaseClass>的实例可以使用的ListConvertAll方法将其转换为List<DerivedClass>

更一般地,如果您有任何实现IEnumerable<T>(不具有ConvertAll方法),你可以使用LINQ的Cast做同样的事情:

IEnumerable<DerivedClass> result = listBaseClass.Cast<DerivedClass>(); 

如果你需要一个List回来,而不是的IEnumerable,你可以直接打电话给ToList()

正如乔恩所说,虽然这都假设listBaseClass中的所有条目实际上都是DerivedClass类型。

相关问题