我有一个基类,比如叫Fruits
。然后,我有几个孩子类,比如说Banana:Fruit
,Apple: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 类做这项工作。
答案 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。