2

我有一个接口 ( IAnimal),它由 Bear 和 Goat 这两个类实现。

在运行时,我可能会得到一个熊或山羊列表,但无论它们是什么,都需要分配给属性IEnumerable<IAnimal>

这有效,因为IEnumerable它是协变的。

但是,我现在需要删除IEnumerable<IAnimal>当然不起作用的项目。

我需要做什么才能删除项目?

这是工作示例:

interface IAnimal {}
public class Bear : IAnimal {}
public class Goat : IAnimal {}

class Program
{
    public static IEnumerable<IAnimal> CouldBeBearsOrGoats { get; set; } 
    static void Main(string[] args) {

        var list = new List<int>() {1, 2, 3};

        var bears = from l in list select new Bear();

        var goats = from l in list select new Goat();

        CouldBeBearsOrGoats = bears;

        CouldBeBearsOrGoats = goats;

        //How do I now remove an item?


    }
}

如果我将 CouldBeBearsOrGoats 更改为列表,那么我可以删除项目,但我不能再分配任何一种类型。

public static List<IAnimal> CouldBeBearsOrGoats { get; set; } 

这份清单会很长,所以我不想只复制一份清单并使用一份副本。我正在做的是处理列表中的每个项目,然后将其删除,直到列表为空。

4

3 回答 3

5

由于您的源数据无论如何都是 IEnumerable,因此您必须将其转换为 List 以添加/删除元素。

    List<IAnimal> ListOfAnimals1 = bears.Cast<IAnimal>().ToList();
    List<IAnimal> ListOfAnimals2 = goats.Cast<IAnimal>().ToList();
于 2013-07-28T22:15:43.443 回答
2

一种可能性是Cast在您的 LINQ 查询中添加一个调用,以便将其转换IEnumerable<Goat>为一个IEnumerable<IAnimal>(实际上创建一个新的迭代器,每个元素都被转换)。

var bears = (from l in list select new Bear()).Cast<IAnimal>().ToList();

var goats = (from l in list select new Goat()).Cast<IAnimal>().ToList();

现在两者bearsgoats都是可枚举的IAnimal,您可以对它们进行操作。

于 2013-07-28T22:15:09.873 回答
0

我认为没有一种简单的方法可以仅使用强类型集合1来做到这一点,因为没有协变集合接口可以公开Remove方法......

我看到了两种可能的解决方案:

  • 使用非通用ICollection接口,由以下方式实现List<T>

    var collection = (ICollection) CouldBeBearsOrGoats;
    collection.Remove(whatever);
    

    缺点是实现的集合ICollection<T>可能无法实现ICollection......

  • 使用动态:

    dynamic collection = CouldBeBearsOrGoats
    collection.Remove(whatever);
    

    但它可能比以前的方法慢。


1假设您不想通过将项目转换为来更改集合的实际类型IAnimal

于 2013-07-28T22:14:51.197 回答