2013-07-28 98 views
2

我有一个接口(IAnimal),它由两个类Bear和Goat实现。如何将List <Bear>或List <Goat>分配到列表<IAnimal>

在运行时,我可能最终会与熊,或山羊的名单,但无论是他们需要被分配到财产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; } 

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

+0

@TimSchmelter,一个'列表'不是'ICollection的',所以它不会解决任何问题 –

+0

通过提供'名单',你允许用户在山羊添加到熊的列表,这可能在您的系统中无效。如果你只想允许删除,也许你应该提供类似'IEnumerable Animals {get {return _animals.AsReadOnly(); }}'和'void RemoveAnimal(IAnimal animal){_animals.Remove(animal); }'。 – nmclean

回答

5

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

List<IAnimal> ListOfAnimals1 = bears.Cast<IAnimal>().ToList(); 
    List<IAnimal> ListOfAnimals2 = goats.Cast<IAnimal>().ToList(); 
+0

不知道为什么这是downvoted;这实际上是一个好的解决方案。 –

+0

这适用于我。 –

0

我不认为有一个简单的方法来做到只使用强类型集合,由于没有协变采集接口,暴露了一个Remove方法...

我看到2个可能的解决方案:

  • 使用非通用ICollection接口,由List<T>实现:

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

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

  • 使用动态:

    dynamic collection = CouldBeBearsOrGoats 
    collection.Remove(whatever); 
    

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


假设你不想铸造项目变更的实际类型的收藏品到IAnimal

2

一个posibility是在你的LINQ查询添加Cast调用,因此它转换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(); 

现在无论bearsgoatsIAnimal枚举接口,你可以对它们进行操作。

相关问题