1

.NET2.0尽管搜索了谷歌和 SO,我似乎无法找到如何做到这一点。

假设我有以下课程:

public class Fruit {
    prop string Color {get; set;}
}

public class Apple : Fruit {
    public Apple() {
        this.Color = "Red";
    }
}

public class Grape: Fruit {
    public Grape() {
        this.Color = "Green";
    }
}

现在我想这样做:

public List<Fruit> GetFruit() {
    List<Fruit> list = new List<Fruit>();
    // .. populate list ..
    return list;
}    


List<Grape> grapes = GetFruit();

但我当然明白了Cannot implicitly convert type Fruit to Grape

我意识到这是因为如果我这样做了,我真的会把事情搞砸:

List<Grape> list = new List<Grape>();
list.add(new Apple());

因为虽然两者都是Fruit,但 anApple不是Grape。所以这是有道理的。

但我不明白为什么我不能这样做:

List<Fruit> list = new List<Fruit>();
list.add(new Apple());
list.add(new Grape());

至少,我需要能够:

List<Fruit> list = new List<Fruit>();
list.add(new Apple());   // will always be Apple
list.add(new Apple());   // will always be Apple
list.add(new Apple());   // will always be Apple

关于如何做到这一点的任何想法.NET2

谢谢

编辑

对不起,我弄错了。我实际上可以这样做:

List<Fruit> list = new List<Fruit>();
list.add(new Apple());
list.add(new Grape());

并且成功.FindAll.Convert

4

4 回答 4

4

我 100% 确定你可以做到这一点:

List<Fruit> list = new List<Fruit>();
list.add(new Apple());
list.add(new Grape());

您为什么要坚持使用 .net 2.0 有什么特别的原因吗?

使用 .net 3.5,您将有两种可能性:

List<Apple> apples = list.OfType<Apple>().ToList();

这将过滤您的列表并返回一个苹果列表。您还有:

List<Apple> apples = list.Cast<Apple>().ToList();

它不会过滤但假设列表中的所有元素都是苹果(如果不是,则抛出和 InvalidCastException)。

于 2012-10-29T15:02:11.870 回答
2

由于您首先需要特定的东西,.Net 2.0我会使用FindAll过滤每个然后使用ConvertAll

List<Grape> grapes = list
  .FindAll(delegate(Fruit f) { return f is Grape; })
  .ConvertAll<Grape>(delegate(Fruit f) { return f as Grape; });

至于你的问题:

但我不明白为什么我不能这样做:

List<Fruit> list = new List<Fruit>();
list.Add(new Apple());
list.Add(new Grape());

您可以这样做,这是完全有效的,您是否输入错误(添加与添加)?

于 2012-10-29T14:53:05.667 回答
2

列表永远不会是协变的,即使在更高版本的 .NET 中也是如此(可枚举是)。

等应该已经可以正常工作了-这list.Add(new Apple())没有问题。

对于作业,您可能必须执行以下操作:

List<Grape> grapes = GetFruit().ConvertAll(x => (Grape)x);

或在较旧的编译器上:

List<Grape> grapes = GetFruit().ConvertAll<Grape>(delegate(Fruit x) {
    return (Grape)x;
});

(在语义上是相同的)

于 2012-10-29T15:00:37.857 回答
0

如果您确定葡萄只会返回Grape对象,则可以使用 LINQ Cast:

Enumerable.Cast 方法

List<Garapes> grapes = GetFruit().Cast<Grape>().ToList();

在进行转换之前,您还可以使用 LINQWhere仅获取葡萄果实

Where(f => f is Grape)

于 2012-10-29T15:07:38.783 回答