2015-11-18 1 views
0

У меня есть ситуация, когда у меня есть общий метод, который принимает объект типа generic, и я хочу написать запрос LINQ для этого объекта.Как написать запрос LINQ в Generic List

Вот пример:

Общий метод:

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); 
+0

'результата вар = persons.PersonList.Where (х =>! x.IsVerified) .ToList(); ' –

+0

@AbhilashPA: PersonList содержит общий список. Так что это не сработает. – user2988458

ответ

3

Вы должны использовать интерфейс, чтобы иметь возможность указать тип учителя и ученика в шаблонного типа. Когда вы используете 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, в которой говорится, что только принимает общий тип TResult при реализации IHuman.

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; 
} 
+0

Вы правы. Но я в ситуации, когда я не могу использовать интерфейс сейчас. Будет очень большое изменение. – user2988458

+1

@ user2988458 см. Обновление, но обратите внимание, что вы должны использовать интерфейс или базовый класс. потому что у всех ваших классов (Учителя и Студента) есть что-то общее. C# - объектно-ориентированный язык, и вы должны использовать его силу! –

+0

Я очень ценю вашу заботу (+1 для этого). Но в вопросе я разместил образец примера. В реальном мире у меня есть более двух классов, которые имеют более 20 свойств, и из этих свойств распространены только два свойства. Один - 'IsVerified', другой -' Name'. :). Поэтому я думаю, что использование отражения - единственное решение. – user2988458

1

Может быть, это может сделать трюк:

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

Я не проверял его в IDE, но что-то, как это будет работать

 Смежные вопросы

  • Нет связанных вопросов^_^