I have two classes. The first one is Person, and the second one is Student (which inherits from Person). I want to filter a generic List and find all Students which grades are higher than 7. I came up with the following solution:
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;
});
}
}
Is there a simpler way to filter this list?
The only improvement I see is using OfType
, like this
var result = people.OfType<Student>().Where(s => s.Grade > 7);
...and my syntax is simpler... but that is in the eye of the beholder.
Here's a few different ways of doing it, with some relative performance numbers:
Initial
people.Where(delegate(Person person)
{
var student = person as Student;
return student != null && student.Grade > 7m;
});
Initial Modified (same speed as Initial)
people.Where(p =>
{
var student = p as Student;
return student != null && student.Grade > 7m;
});
OfType (40-52% SLOWER than Initial)
people.OfType<Student>().Where(s => s.Grade > 7m)
Foreach (9-16% faster than Initial)
var results = new List<Student>();
foreach (var person in people)
{
var student = person as Student;
if (student != null && student.Grade > 7m)
{
results.Add(student);
}
}
For (12-18% faster than initial)
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);
}
}
Of course, these are just performance numbers on my machine, you'll have to test on real-world data to get actual results as the distribution of Students vs. People, the average grade of the student, etc. will cause a lot of variation in the timings.
people.RemoveAll(p => p.Grade <= 7);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With