[英]LINQ: From a list of type T, retrieve only objects of a certain subclass S
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 的结果,而不必为每种可能的类型编写一个方法。
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 约束。
这应该可以解决问题。
var students = persons.Where(p => p.GetType() == typeof(Student));
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.但是您真正所做的只是用一个更安全的版本重写 LINQ 的 OfType() 方法,该版本使用静态类型检查来确保您传入一个 Person。 You still can't use this method with a type that's determined at runtime (unless you use reflection).您仍然不能将此方法用于在运行时确定的类型(除非您使用反射)。
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.现在您可以动态构造某种类型并使用它来调用此方法。
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;
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.