• C# 集合的扩展方法-查询表达式GroupBy()的使用 转


    原文链接 : https://www.cnblogs.com/knightcoming/articles/6107755.html

    c#中查询表达式GroupBy的使用

    说明:

    c#中实现IEnumerable<T>接口的类提供了很多扩展方法,其中Select,Where等为最常见的,且几乎和Sql语法类似比较好理解,基本满足了日常处理集合的大部分需求,然而还有一部分稍有不一样理解起来比较拗,实际分析一下实现的原理倒也很好理解,本篇文章介绍一下GroupBy的使用方法。

    实验基础数据用例:

    Student类:

    复制代码
     public class Student
        {
            public int StuId { get; set; }
    
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> ClassName { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }
    
        </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> StudentName { <span style="color: #0000ff;">get</span>; <span style="color: #0000ff;">set</span><span style="color: #000000;">; }
    }</span></pre>
    
    复制代码

    设定数据如下:

    复制代码
    List<Student> studentList = new List<Student>
                {
                    new Student {ClassName = "软工一班", StudentName = "康巴一", StuId = 1},
                    new Student {ClassName = "软工一班", StudentName = "康巴二", StuId = 2},
                    new Student {ClassName = "软工一班", StudentName = "康巴三", StuId = 3},
                    new Student {ClassName = "软工二班", StudentName = "康定一", StuId = 4},
                    new Student {ClassName = "软工二班", StudentName = "康定二", StuId = 5},
                    new Student {ClassName = "软工二班", StudentName = "康定三", StuId = 6},
                };
    复制代码

    我们假设两个班里的学生总共有六名,现在根据班级分组

    IEnumerable<IGrouping<string, Student>> studentGroup = studentList.GroupBy(s => s.ClassName);

    如代码,调用GroupBy扩展方法后,返回类型为IEnumerable<IGrouping<string, Student>>, IEnumerable代表了返回结果可被foreach遍历,其中泛型实现为IGrouping<string,Student>,按照普遍理解的分组的概念,可以推断IGrouping中应该是string代表的是一个key,即ClassName,那么key对应的应该就是一个Student的集合,但是代码应该怎样实现呢?

    可以首先foreach一下studentGroup

      foreach (IGrouping<string, Student> item in studentGroup)
                {
    
            }</span></pre>
    

    这时候可以item.一下看看提示信息

    这时候发现,只能提示出来的属性只有一个key,那么怎样通过item获取到分组后的Student集合呢?这时候发现第二个GetEnumerator()方法,这个说明了item是可以被foreach的,类型为IEnumerator<Student>,说明了可被遍历的类型为Student

    然后可以foreach下item试一试

    如果所示,果然是Student,根据推断,现在在foreach中遍历所有数据,然后打出来看一下

    复制代码
    foreach (IGrouping<string, Student> item in studentGroup)
                {
                    Console.WriteLine(item.Key);
                    foreach (var student in item)
                    {
                        Console.WriteLine(student.StudentName);
                    }
                }
    复制代码

    执行结果如下:

    所以可以断定item是一个Student的集合,那么为什么item还有个key属性呢,好像是和平常的集合不太一样,事实确实是不一样的,我们看下IGrouping的定义如下:

    复制代码
    public interface IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable
      {
        /// <summary>
        /// 获取 <see cref="T:System.Linq.IGrouping`2"/> 的键。
        /// </summary>
        /// 
        /// <returns>
        /// <see cref="T:System.Linq.IGrouping`2"/> 的键。
        /// </returns>
        [__DynamicallyInvokable]
        TKey Key { [__DynamicallyInvokable] get; }
      }
    复制代码

    IGrouping的key是作为自己的属性来存储了,TElement则实现了IEnumerable<TElement>,所以调用foreach遍历IGrouping的时候返回的即是Student的集合了

    这个探索是挺有趣的,通过神器vs的智能提示和源码的实现最终知道了GroupBy的用法,并且了解了为什么这样用。

    同时也看出了通过接口可以巧妙的实现多态,其中自然是妙趣无穷!

     

  • 相关阅读:
    OpenGL ES学习001---绘制三角形
    Mac关机时处于黑屏状态
    静态变量和实例变量的区别(配图解释专业术语,通俗易懂)
    用shape画内圆外方,形成一个圆形头像
    最全的敏捷认证对比(CSM/PMI-ACP/EXIN)
    Certified Scrum Master CSM 中文资料大全
    如何打造优秀的远程敏捷团队(9步)
    博客搬家
    权威的国际敏捷认证Certified Scrum Master (CSM)
    博客园入驻了
  • 原文地址:https://www.cnblogs.com/sunny3158/p/11694059.html
Copyright © 2020-2023  润新知