C# LINQ:从类型 T 的列表中,仅检索某个子类 S 的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1184944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LINQ: From a list of type T, retrieve only objects of a certain subclass S
提问by Hythloth
Given a simple inheritance hierarchy: Person -> Student, Teacher, Staff
给定一个简单的继承层次结构:Person -> Student、Teacher、Staff
Say I have a list of Persons, L. In that list are some Students, Teachers, and Staff.
假设我有一个 Person 列表,L。在该列表中是一些学生、教师和工作人员。
Using LINQ and C#, is there a way I could write a method that could retrieve only a particular type of person?
使用 LINQ 和 C#,有没有一种方法可以编写一种只能检索特定类型人的方法?
I know I can do something like:
我知道我可以这样做:
var peopleIWant = L.OfType< Teacher >();
But I want to be able to do something more dynamic. I would like to write a method that will retrieve results for any type of Person I could think of, without having to write a method for every possible type.
但我希望能够做一些更有活力的事情。我想编写一个方法来检索我能想到的任何类型的 Person 的结果,而不必为每种可能的类型编写一个方法。
采纳答案by Mladen Prajdic
you can do this:
你可以这样做:
IList<Person> persons = new List<Person>();
public IList<T> GetPersons<T>() where T : Person
{
return persons.OfType<T>().ToList();
}
IList<Student> students = GetPersons<Student>();
IList<Teacher> teacher = GetPersons<Teacher>();
EDIT: added the where constraint.
编辑:添加了 where 约束。
回答by kareem
This should do the trick.
这应该可以解决问题。
var students = persons.Where(p => p.GetType() == typeof(Student));
回答by Richard Berg
You could do this:
你可以这样做:
IEnumerable<Person> GetPeopleOfType<T>(IEnumerable<Person> list)
where T : Person
{
return list.Where(p => p.GetType() == typeof(T));
}
But all you've really done is rewrite LINQ's OfType() method with a safer version that uses static type checking to ensure you pass in a Person. You still can't use this method with a type that's determined at runtime (unless you use reflection).
但是您真正所做的只是用一个更安全的版本重写 LINQ 的 OfType() 方法,该版本使用静态类型检查来确保您传入一个 Person。您仍然不能将此方法用于在运行时确定的类型(除非您使用反射)。
For that, rather than using generics, you'll have to make the type variable a parameter:
为此,您必须将类型变量设为参数,而不是使用泛型:
IEnumerable<Person> GetPeopleOfType(IEnumerable<Person> list, Type type)
{
if (!typeof(Person).IsAssignableFrom(type))
throw new ArgumentException("Parameter 'type' is not a Person");
return list.Where(p => p.GetType() == type);
}
Now you can construct some type dynamically and use it to call this method.
现在您可以动态构造某种类型并使用它来调用此方法。
回答by Shahar Shokrani
For general list, using delegate
:
对于一般列表,使用delegate
:
public List<T> FilterByType(List<T> items, Type filterType)
{
return items.FindAll(delegate(T t)
{
return t.GetType() == filterType;
});
}