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

说明:

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

 

实验基础数据用例:

Student类:

复制代码

 public class Student
    {
        public int StuId { get; set; }

        public string ClassName { get; set; }

        public string StudentName { get; set; }
    }

复制代码

设定数据如下:

复制代码

List<Student> studentList = new List<Student>
            {
                new Student {ClassName = "软工一班",StudentName = "康巴一",StuId = 1},new Student {ClassName = "软工一班",StudentName = "康巴二",StuId = 2},StudentName = "康巴三",StuId = 3},new Student {ClassName = "软工二班",StudentName = "康定一",StuId = 4},StudentName = "康定二",StuId = 5},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)
            {
                
            }

 

这时候可以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的用法,并且了解了为什么这样用。

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

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...