3

我有一个基类,比如说叫做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

4 回答 4

14

框架中已经存在这样的方法 - OfType<T>

List<Banana> bananas = f.OfType<Banana>().ToList();
于 2012-05-05T16:20:27.873 回答
2

您需要一个通用方法,例如:

    public List<T> GimmeAnyOfType<T>(List<Fruit> f)
    {
        return f.OfType<T>().ToList();
    } 
于 2012-05-05T16:26:16.987 回答
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;
     }
}
于 2012-05-05T16:22:16.067 回答
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;
        }
    }
}

此运算符仅在您具有平面派生层次结构时才有效。如果您有例如 Apples 作为从水果派生的基类,并且您有专门的苹果,如 GoldenDelicius、RedDelicus ......并且您想计算所有类型为 apple 但不是派生的苹果,您不能使用 OfType 运算符来做到这一点。为此,您仍然需要一个额外的功能。在示例中,它被称为 GetOfExactType。

于 2012-05-05T16:25:09.823 回答