Ответ 1
Единственное улучшение, которое я вижу, это использовать OfType
, как этот
var result = people.OfType<Student>().Where(s => s.Grade > 7);
... и мой синтаксис проще... но это в глазах смотрящего.
У меня есть два класса. Первый - это Person, а второй - Student (который наследуется от Person). Я хочу отфильтровать общий список и найти все Студенты, которые имеют выше 7. Я придумал следующее решение:
class Person
{
public string Name {get; set;}
}
class Student : Person
{
public decimal Grade {get; set;}
}
class Program
{
static void Main(string[] args)
{
List<Person> people = new List<Person>();
people.Add(new Person() {Name="John"});
people.Add(new Student() {Name="Joe", Grade=6});
people.Add(new Student() {Name="Jane", Grade=8});
people.Where(delegate (Person person) {
var student = person as Student;
return student != null && student.Grade > 7;
});
}
}
Есть ли более простой способ фильтрации этого списка?
Единственное улучшение, которое я вижу, это использовать OfType
, как этот
var result = people.OfType<Student>().Where(s => s.Grade > 7);
... и мой синтаксис проще... но это в глазах смотрящего.
Вот несколько разных способов сделать это, с некоторыми относительными номерами производительности:
Начальное
people.Where(delegate(Person person)
{
var student = person as Student;
return student != null && student.Grade > 7m;
});
Начальное изменение (с той же скоростью, что и начальная)
people.Where(p =>
{
var student = p as Student;
return student != null && student.Grade > 7m;
});
OfType (40-52% SLOWER, чем начальное)
people.OfType<Student>().Where(s => s.Grade > 7m)
Foreach (На 9-16% быстрее Начального)
var results = new List<Student>();
foreach (var person in people)
{
var student = person as Student;
if (student != null && student.Grade > 7m)
{
results.Add(student);
}
}
Для (На 12-18% быстрее первоначального)
var results = new List<Student>();
for (var idxPerson = 0; idxPerson < people.Count; idxPerson++)
{
var student = people[idxPerson] as Student;
if (student != null && student.Grade > 7m)
{
results.Add(student);
}
}
Конечно, это всего лишь номера производительности на моей машине, вам нужно будет проверить данные в реальном мире, чтобы получить фактические результаты, поскольку распределение учеников и людей, средний класс ученика и т.д. приведет к много изменений в таймингах.
people.RemoveAll(p => p.Grade <= 7);