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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17255942/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 08:58:36  来源:igfitidea点击:

Simplest way to filter value from generic List in C# using LINQ

c#linq

提问by Eduardo Matos

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 Listand find all Studentswhich grades are higher than 7. I came up with the following solution:

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

Is there a simpler way to filter this list?

有没有更简单的方法来过滤这个列表?

采纳答案by Hogan

The only improvement I see is using OfType, like this

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

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

...and my syntax is simpler... but that is in the eye of the beholder.

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

回答by steve

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)

OfType(比初始慢40-52%)

people.OfType<Student>().Where(s => s.Grade > 7m)

Foreach(9-16% faster than Initial)

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

For(12-18% faster than initial)

对于(比初始速度快 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);
    }
}

To get the performance numbers, I:

为了获得性能数据,我:

  • Ran a control test that did nothing
  • Timed each of the functions 100 times over a List with 10 to 1,000,000 elements
  • Subtracted the control time from each tests time (to make the results more accurate)
  • Each function used the same random data set and ToList was used to force the enumerator to run
  • 进行了一个什么都没做的对照测试
  • 对具有 10 到 1,000,000 个元素的 List 对每个函数进行 100 次计时
  • 从每次测试时间中减去控制时间(使结果更准确)
  • 每个函数使用相同的随机数据集,并使用 ToList 强制枚举器运行

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.

当然,这些只是我机器上的表现数字,你必须在真实世界的数据上进行测试才能得到实际结果,因为学生与人的分布、学生的平均成绩等会导致很多时间的变化。

回答by Jannie Theunissen

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