LINQ:从T类型的列表,检索某些子类S的唯一对象(LINQ: From a list of typ

2019-06-26 20:32发布

给定一个简单的继承层次:人 - >学生,教师和工作人员

说我有人员名单,L.在该列表中有一些学生,教师和工作人员。

使用LINQ和C#,是有办法,我可以写,可以只检索特定类型的人的方法?

我知道我可以这样做:

var peopleIWant = L.OfType< Teacher >();

但我希望能够做一些更有活力。 我想编写,将检索我能想到的任何类型的人的结果的方法,而无需编写了所有可能的方法。

Answer 1:

你可以这样做:

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>();

编辑:加入其中约束。



Answer 2:

这应该做的伎俩。

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


Answer 3:

你可以这样做:

IEnumerable<Person> GetPeopleOfType<T>(IEnumerable<Person> list)
    where T : Person
{
    return list.Where(p => p.GetType() == typeof(T));
}

但是,所有你真的做的是重写LINQ的OfType()方法与使用静态类型检查,以确保你一个人传递一个更安全的版本。 您仍然无法与同时在运行时确定的(除非您使用反射)一类使用此方法。

对于这一点,而不是使用泛型,你必须使类型变量的参数:

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);
}

现在,您可以动态地构造某种类型,并用它来调用这个方法。



Answer 4:

对于一般的列表,使用delegate

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


文章来源: LINQ: From a list of type T, retrieve only objects of a certain subclass S