lambda参数如何工作?

时间:2017-01-02 02:02:15

标签: c# linq

我们说我们有一个班级学生

class Student
{
    public string Name { get; set; }
    public string Gender { get; set; }
    public List<string> Subjects { get; set; }

    public static List<Student> GetAllStudetns()
    {
        List<Student> listStudents = new List<Student>
        {
           new Student
           {
               Name = "Tom",
               Gender = "Male",
               Subjects = new List<string> { "ASP.NET", "C#" }
           },
           new Student
           {
              Name = "Mike",
               Gender = "Male",
               Subjects = new List<string> { "ADO.NET", "C#", "AJAX" }
           }
        };

        return listStudents;
    }
}

我们想要打印每个学生这样的科目:

  

Tom - ASP.NET

     

汤姆 - C#

     

Mike - ADO.NET

     迈克 - C#

     

所以我找到的答案是

var result = Student.GetAllStudents().SelectMany(s => s.Subjects, (student, subject) => new { StudentName = student.Name, SubjectName = subject});

//then use foreach loop to retrieve...

我可以理解=&gt;的第二次使用,这只是对匿名类型的投影。但我不明白第一部分

s => s.Subjects, (student, subject)

根据我的理解,左侧=&gt;是intput参数,在这种情况下是Student实例s,但是右边的=&gt;应该是与Student实例相关的返回类型,例如s.Name,如果我们想获得学生的名字,那么(学生,主题)是什么意思?

2 个答案:

答案 0 :(得分:2)

这是因为Subjects在类中被定义为List<string>,你必须单独打印它,所以它需要迭代子列表的集合。在解释查询的请求部分(s => s.Subjects, (student, subject))之前,您应该先了解.SelectMany

的定义
public static IEnumerable<TResult> SelectMany<TSource, TResult>(
    this IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TResult>> selector
)

根据方法的签名,第二个参数(Func)接受源对象(此处为Student类型)和IEnumerable个集合对象,此处为是字符串类型,因为它是List<string>

这意味着(student, subject)中的学生属于Student类型且主题将是s.Subjects中的项目,因此.SelectMany将进一步遍历子集合。< / p>

如果你想这样打印(Tom - ASP.NET,C#)意味着你可以在你的情况下做GroupBy你不想这样做,所以使用该代码对子列表进行迭代;

其他信息:如果结果基于分组,那么您的代码将如下所示:

var result = Student.GetAllStudents()
                    .GroupBy(s => s.Name)
                    .Select(x=> new { StudentName = x.Key, SubjectName = String.Join(",",
                   x.SelectMany(y=>y.Subjects)
                    .ToList()});

答案 1 :(得分:2)

SelectMany已超载。见https://msdn.microsoft.com/en-us/library/bb534631(v=vs.110).aspx

s => s.Subjects是您的集合选择器 - 将应用于输入

的每个元素的转换

(student, subject) => new { StudentName = student.Name, SubjectName = subject}是你的结果选择器 - 应用于中间序列的每个元素的转换函数