使用LINQ从C#中的genericsList过滤值的最简单方法
我有两节课。 第一个是Person ,第二个是Student (inheritance自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 people = new List(); 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().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%)
people.OfType().Where(s => s.Grade > 7m)
Foreach (比起初速度快9-16%)
var results = new List(); 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(); 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个元素的List上定时100次
- 从每个测试时间中减去控制时间(以使结果更准确)
- 每个函数使用相同的随机数据集,并使用ToList强制枚举器运行
当然,这些只是我机器上的性能数字,你必须测试真实世界的数据以获得实际结果,因为学生与人的分布,学生的平均成绩等会导致很多时间的变化。
people.RemoveAll(p => p.Grade <= 7);