从List<>中查找特定类的对象

时间:2012-05-05 16:18:08

标签: c# generic-list

我有一个基类,比如叫Fruits。然后,我有几个孩子类,比如说Banana:FruitApple:Fruit等等。

然后我有一个不同类型的对象列表,香蕉,苹果,等等。看起来像这样:

List<Fruits> f = new List<Fruits>{new Banana(), new Banana(), new Apple(), new Banana()};

我想要一个可以获取水果列表和类型的函数,并给我一个列表,列表中只包含该类型的对象。所以,如果我打电话给find_obj(f, Banana),(或其他什么),它应该给我一个只包含香蕉的清单。

我可能在这里表现出极度的无知,我道歉。这甚至可能吗?我知道如果我事先知道这个课,我可以做这样的事情:

public List<Fruit> GimmeBanana(List<Fruit> f)
{
     List<Fruit> Output=new List<Fruit>{ };
     foreach(Fruit fr in f)
     {
         if (fr is Banana){ Output.Add(fr); }
     }
}

但我不知道如何为 Any 类做这项工作。

4 个答案:

答案 0 :(得分:12)

这种方法已经存在于框架中 - OfType<T>

List<Banana> bananas = f.OfType<Banana>().ToList();

答案 1 :(得分:1)

即使您应该使用其他答案所指出的OfType,作为一种学习经历,我也会按照以下方式编写您的方法:

public IEnumerable<Banana> GimmeBananas(List<Fruit> f)
{
     if (f == null) yield break; //depending on what business logic you're looking for.
     foreach(Fruit fr in f)
     {
         if (fr is Banana) yield return fr;
     }
}

答案 2 :(得分:1)

你需要一个通用的方法,如:

    public List<T> GimmeAnyOfType<T>(List<Fruit> f)
    {
        return f.OfType<T>().ToList();
    } 

答案 3 :(得分:0)

您可以使用LINQ OfType运算符仅从集合中选择具有匹配类型的元素。

class Fruit { }
class Banana : Fruit{}
class Apple : Fruit{}

static void Main(string[] args)
{
    var fruits = new List<Fruit> { new Banana(),  new Banana(), new Apple(), new Fruit() };
    int bananas = fruits.OfType<Banana>().Count(); // 2
    int apples = fruits.OfType<Apple>().Count(); // 1
    int fruitc = fruits.OfType<Fruit>().Count(); // 4
    int exactFruits = GetOfExactType<Fruit,Fruit>(fruits).Count();  // 1
}


static IEnumerable<V> GetOfExactType<T, V>(IEnumerable<T> coll)
{
    foreach (var x in coll)
    {
        if (x.GetType().TypeHandle.Value == typeof(V).TypeHandle.Value)
        {
            yield return (V)(object)x;
        }
    }
}

此运算符仅在您具有平坦的派生层次结构时才起作用。如果您有例如苹果作为从水果派生的基类,你有专门的苹果,如GoldenDelicius,RedDelicus,...你想要计算苹果类型的所有苹果,但不是使用OfType运算符你不能做的派生的苹果。为此你还需要一个额外的功能。在示例中,它被称为GetOfExactType。

相关问题