如何在泛型列表上编写LINQ查询

本文关键字:LINQ 查询 列表 泛型 | 更新日期: 2023-09-27 18:22:31

我有一种情况,我有一个接受泛型类型对象的泛型方法,并且我想对该对象编写LINQ查询。

这里有一个例子:

通用方法:

public static void GetNonNonVerifiedPersons<TResult>(Person<TResult> model)
{
      // How To Write LINQ Here to get non verified person      
}

学生班:

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsVerified { get; set; }
}

教师班:

public class Teacher
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsVerified { get; set; }
}

人员类别:

public class Person<T>
{
    public List<T> PersonList { get; set; }
}

主要类别:

// 1. Get Non Verified Students
var persons = new Person<Student>();
var students = new List<Student>()
                    {
                        new Student { Id = 1, Name = "Student_A", IsVerified = true },
                        new Student { Id = 2, Name = "Student_B", IsVerified = false },
                    };
 persons.PersonList = new List<Student>();
persons.PersonList.AddRange(students);
GetNonNonVerifiedPersons(persons);

// 2. Get Non Verified Teachers
var persons2 = new Person<Teacher>();
var teachers = new List<Teacher>()
                    {
                        new Teacher { Id = 1, Name = "Teacher_A", IsVerified = true },
                        new Teacher { Id = 2, Name = "Teacher_B", IsVerified = false },
                        new Teacher { Id = 3, Name = "Teacher_C", IsVerified = false },
                    };
persons2.PersonList = new List<Teacher>();
persons2.PersonList.AddRange(teachers);
GetNonNonVerifiedPersons(persons2);

如何在泛型列表上编写LINQ查询

您应该使用接口来指定泛型类型中的教师和学生的类型。当您使用where子句时,编译器能够在编译时进行类型检查。

public interface IHuman
{  
    string Name { get; set; }
    bool IsVerified { get; set; }
}
public class Teacher : IHuman
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsVerified { get; set; }
}
public class Student : IHuman
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsVerified { get; set; }
}

然后你的方法应该是这样的。这里我们有where子句,它表示在实现IHuman时只接受泛型类型TResult。

public static IEnumerable<TResult> GetNonNonVerifiedPersons<TResult>(Person<TResult> model) where TResult : IHuman
{
    return model.PersonList.Where(x => !x.IsVerified);
}

更新:我强烈建议你做出大的改变,因为它应该是这样的。

另一种不常见且非常缓慢的方法是在运行时检查类型。

public static IEnumerable<TResult> GetNonNonVerifiedPersons<TResult>(Person<TResult> model)
{
    var list = model.PersonList;
    var t = list.FirstOrDefault() as Teacher;
    if (t != null)
    {
        return model.PersonList.Where(x => !(x as Teacher).IsVerified);
    }
    var s = list.FirstOrDefault() as Student;
    if (s != null)
    {
        return model.PersonList.Where(x => !(s as Student).IsVerified);
    }
    return null;
}

可能是这样可以做到的:

IList<Person<TResult>> xyz = new List<Person<TResult>>();
var list = xyz.Where(a => a.GetType() == typeof(Student).IsVerified);

我没有在IDE中检查它,但像这样的东西可以工作