在C#中,是否可以将List <child>转换为List <parent>?</parent> </child>

时间:2009-11-22 04:22:05

标签: c# inheritance casting

我想做这样的事情:

List<Child> childList = new List<Child>();
...
List<Parent> parentList = childList;

但是,因为parentList是Child的祖先的 List ,而不是直接的祖先,所以我无法做到这一点。是否有解决方法(除了单独添加每个元素)?

5 个答案:

答案 0 :(得分:67)

使用LINQ:

List<Parent> parentList = childList.Cast<Parent>().ToList();

Documentation for Cast<>()

答案 1 :(得分:57)

不允许直接进行转换,因为无法使其类型安全。如果你有长颈鹿的名单,并将它投入到动物名单中,那么你可以将老虎放入长颈鹿名单中!编译器不会阻止你,因为当然老虎可能会进入动物列表。编译器可以阻止你的唯一地方是不安全的转换。

在C#4中,我们将支持SAFE接口和使用引用类型参数化的委托类型的协方差和逆变。有关详细信息,请参见此处:

http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx

答案 2 :(得分:4)

早在2009年,Eric就嘲笑我们C#4会有所改变。那么我们今天在哪里?

我的答案中使用的类可以在底部找到。为了更容易理解,我们将Mammal类用作“父级”,将CatDog类用作“子级”。猫和狗都是哺乳动物,但猫不是狗,狗不是猫。

这仍然不合法,不能是:

List<Cat> cats = new List<Cat>();

List<Mammal> mammals = cats;

为什么不呢?猫是哺乳动物,为什么我们不能将猫列表分配到List<Mammal>

因为,如果允许我们在List<Cat>变量中存储对List<Mammal>的引用,那么我们就可以编译以下代码来将狗添加到猫列表中:

mammals.Add(new Dog());

我们绝不允许这样!请注意,mammals只是对cats的引用。 Dog并非来自Cat,并且没有商家位于Cat个对象的列表中。

Starting with .NET Framework 4,几个通用接口具有使用C#4中引入的out Generic Modifier关键字声明的协变类型参数。这些接口中的IEnumerable<T>当然是由{{1}实现的}}

这意味着我们可以现在将List<T>投放到List<Cat>

IEnumerable<Mammal>

我们无法向IEnumerable<Mammal> mammalsEnumerable = cats; 添加新的Dog,因为mammalsEnumerable是“只读”界面,即它没有IEnumerable<out T>方法,但我们 现在可以使用Add(),只要cats可以消费。例如,我们可以将IEnumerable<Mammal>mammalsEnumerable连接起来以返回新序列:

List<Dog>

班级定义:

void Main()
{
    List<Cat> cats = new List<Cat> { new Cat() };
    IEnumerable<Mammal> mammalsEnumerable =
        AddDogs(cats); // AddDogs() takes an IEnumerable<Mammal>
    Console.WriteLine(mammalsEnumerable.Count()); // Output: 3. One cat, two dogs.
}

public IEnumerable<Mammal> AddDogs(IEnumerable<Mammal> parentSequence)
{
    List<Dog> dogs = new List<Dog> { new Dog(), new Dog() };
    return parentSequence.Concat(dogs);
}

答案 3 :(得分:0)

是的,你可以像

那样做
var result = List.And(x => x.Parent.All(b => b.ParentId == value));

答案 4 :(得分:-2)

您可以使用应用扩展方法的Linq方法,即:

List<Parent> parentList = childList.Cast<Parent>().ToList();