如何在通用列表上编写LINQ查询

时间:2015-11-18 04:45:38

标签: c# linq generics generic-list

我有一种情况,我有一个泛型方法,它接受泛型类型的对象,我想在该对象上写一个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);

2 个答案:

答案 0 :(得分:3)

您应该使用interface来指定泛型类型的Teacher和Student类型。当您使用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;
}

答案 1 :(得分:1)

可能这可以解决问题:

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

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