LINQ: From a list of type T, retrieve only objects of a certain subclass S

怎甘沉沦 提交于 2019-12-17 10:53:10

问题


Given a simple inheritance hierarchy: Person -> Student, Teacher, Staff

Say I have a list of Persons, L. In that list are some Students, Teachers, and Staff.

Using LINQ and C#, is there a way I could write a method that could retrieve only a particular type of person?

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.


回答1:


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.




回答2:


This should do the trick.

var students = persons.Where(p => p.GetType() == typeof(Student));



回答3:


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).

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.




回答4:


For general list, using delegate:

public List<T> FilterByType(List<T> items, Type filterType)
{
    return items.FindAll(delegate(T t)
    {
        return t.GetType() == filterType;
    });
}


来源:https://stackoverflow.com/questions/1184944/linq-from-a-list-of-type-t-retrieve-only-objects-of-a-certain-subclass-s

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!