【问题标题】:How do lambda parameters work?lambda 参数如何工作?
【发布时间】:2017-01-03 00:27:00
【问题描述】:

假设我们有一个班级学生

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

我们想打印出每个学生的科目如下:

汤姆 - ASP.NET

汤姆 - C#

迈克 - 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...

我可以理解 => 的第二种用法,它只是投影到匿名类型。但我不明白第一部分

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

根据我的理解,=>左边是输入参数,在这种情况下是Student实例s,但=>右边应该是与Student实例s相关的返回类型,例如s.Name if我们想得到学生的名字,那么 (student, subject) 是什么意思?

【问题讨论】:

    标签: c# linq


    【解决方案1】:

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

    s =&gt; s.Subjects 是您的集合选择器 - 将应用于输入的每个元素的转换

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

    【讨论】:

    • 谢谢。现在我明白了。我应该看到逗号作为分隔符
    • 请补充一些关于s =&gt; Subjects(...) =&gt; ... 是不同的东西,而不是s =&gt; s.Subjects, (...)
    【解决方案2】:

    这是因为Subjects在类内部定义为List&lt;string&gt;,你必须单独打印它,所以它需要遍历子列表的集合。在解释查询的请求部分(s =&gt; 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&lt;string&gt;

    这意味着(student, subject) 中的学生是Student 类型,并且主题将是s.Subjects 中的一个项目,因此.SelectMany 将进一步迭代这里的子集合。

    如果您想这样打印(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()});
    

    【讨论】:

    • 那么什么是(学生,科目)?是组合参数吗?
    • 你在回答被问到的问题吗?
    猜你喜欢
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多