先定义一些我们使用的类:
Code
class School
{
private IList<Class> m_Classes = new List<Class>();
internal IList<Class> Classes
{
get { return m_Classes; }
set { m_Classes = value; }
}
}
class Class
{
private IList<Student> m_Students = new List<Student>();
internal IList<Student> Students
{
get { return m_Students; }
set { m_Students = value; }
}
}
class Student
{
public Student(int i, string name)
{
m_Sex = i;
m_Name = name;
}
private string m_Name;
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
private int m_Sex;
public int Sex
{
get { return m_Sex; }
set { m_Sex = value; }
}
}
说明:
类School下面有一个Class的集合,每个Class下面有有一个Student的集合。每个学生有Name和Sex两个属性。现在需要遍历School下面的所有的学生,当然我们可以用两个嵌套的foreach语句类遍历School下面的所有的Class,然后再用foreach来遍历Class下面的所有的Student,把他们添加到一个List里去。这个场景也是实际编程中经常遇到的。有了Linq我们就可以大大的简化我们的代码:
Code
static void Main(string[] args)
{
//初始化数据
School s = new School();
for (int i = 0; i < 5; i++)
{
s.Classes.Add(new Class());
}
s.Classes[0].Students.Add(new Student(1, "a0"));
s.Classes[1].Students.Add(new Student(1, "b0"));
s.Classes[2].Students.Add(new Student(0, "c0"));
s.Classes[3].Students.Add(new Student(0, "d0"));
s.Classes[4].Students.Add(new Student(0, "e0"));
s.Classes[0].Students.Add(new Student(0, "a1"));
s.Classes[0].Students.Add(new Student(1, "a1"));
s.Classes[0].Students.Add(new Student(1, "a2"));
s.Classes[0].Students.Add(new Student(1, "a3"));
s.Classes[1].Students.Add(new Student(0, "b1"));
s.Classes[2].Students.Add(new Student(0, "c1"));
s.Classes[3].Students.Add(new Student(0, "d1"));
//取出school下的所有性别是0的student
var x = s.Classes.SelectMany(b => b.Students).Where(i => i.Sex == 0);
foreach (var b in x)
{
Console.WriteLine(b.Name);
}
Console.ReadKey();
}
我们之需要用一下SelectMany就可以了,不用去用foreach进行两次遍历。SelectMany在MSDN中的解释:将序列的每个元素投影到 IEnumerable(T) 并将结果序列合并为一个序列。
Select 与 SelectMany 都属于投影运算
Select() 和 SelectMany() 的工作都是依据源值生成一个或多个结果值。Select() 为每个源值生成一个结果值。因此,总体结果是一个与源集合具有相同元素数目的集合。与之相反,SelectMany() 将生成单一总体结果,其中包含来自每个源值的串联子集合。作为参数传递到 SelectMany() 的转换函数必须为每个源值返回一个可枚举值序列。然后,SelectMany() 将串联这些可枚举序列以创建一个大的序列。
参考MSDN:
ms-help://MS.MSDNQTR.v90.chs/fxref_system.core/html/3371348f-7811-b0bc-8c0a-2a595e08e086.htm
http://msdn.microsoft.com/zh-cn/library/bb546168.aspx