使用LINQ从C#中的泛型List过滤值的最简单方法

时间:2013-06-22 22:32:23

标签: c# linq

我有两节课。第一个是 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;
        });
    }
}

是否有更简单的方法来过滤此列表?

3 个答案:

答案 0 :(得分:29)

我看到的唯一改进就是使用OfType,就像这样

var result = people.OfType<Student>().Where(s => s.Grade > 7);

...而且我的语法更简单......但这是旁观者的眼睛。

答案 1 :(得分:4)

以下是一些不同的方法,有一些相对的性能数字:

<强>初始

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%)

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);
    }
}

要获得性能数字,我:

  • 进行无效的对照测试
  • 将每个功能在具有10到1,000,000个元素的列表上定时100次
  • 从每个测试时间中减去控制时间(以使结果更准确)
  • 每个函数使用相同的随机数据集,并使用ToList强制枚举器运行

当然,这些只是我机器上的性能数字,您必须测试真实数据,以获得实际结果,如学生与人的分布,学生的平均成绩等。会导致时间的变化很大。

答案 2 :(得分:1)

people.RemoveAll(p => p.Grade <= 7);