c# GroupBy的基本使用教程

  


  

  

今天在公司做一个需求的时候,写的是面条代码,一个方法直接从头写到尾,其中用到了GroupBy,且GroupBy的KeySelector是多个属性而不是单个属性。

  

但是公司最近推干净代码行,要让代码有可读性。且作为一个有追求的程序员,肯定是不能写面条代码的,要对代码进行拆分。

  

重构前GroupBy大概是这样子的:

        var=数据组。GroupBy (m=比;新{m。PropertyA m.PropertyB})      

个人对于短的Linq比较习惯于用方法而不是用关键字的那种写法。

  

一开始这样写是没问题的,但是重构的时候问题就来了:这个团体是什么类型?

  

重构以后这个组是要作为参数进入到别的方法中的,方法签名显然是不能用var做类型推导,必须指定确定的类型。

  

我们知道GroupBy出来的东西是个泛型的东西,签名是IEnumerable祝辞,这个TSource类型是没问题,我没有对源代码做修改,就数据是本身的类型。

  

但是这个关键就有问题了。

  

我没有指定关键的类型,这里应该是匿名类型,于是定义了一个类型承接钥匙,代码变成了:

        类EntityKey   {   公共int PropertyA{设置;}   公共字符串PropertyB{设置;}   }      ……      var=数据组。GroupBy (m=比;新EntityKey {PropertyA=m。PropertyA PropertyB=m.PropertyB});      

但是后来我发现这样有问题,GroupBy指定的关键失效了。也就是说,组织的分组数量与数据的长度一致,每一个组里面只有一个对象。

  


  

  

发现这个问题后,我仔细思考了一下,大致猜到了问题出在哪里。

  

GroupBy这种东西,判断两个对象是不是一个分组,必然用到了相等判断。

  

虽然我没有看匿名类型反编译生成后的IL代码,不知道之前用的是怎么做的关键相等判断,但是引用类型的肯定是直接用对象的HashCode做判断。

  

这样子肯定是不行的,要解决引用类型的相等判断问题。

  


  

  

根据猜测,我写了一个示例程序最小化的重现了这个问题:

        类项目   {   静态void Main (string [] args)   {   var=new List<列表;Student> ();   列表。添加(新学生(1,“猫”,“University1”));   列表。添加(新学生(2中,“狗”10 " University1 "));   列表。添加(新学生(3,“猪”,10日,“University2”));   列表。添加(新学生(4,“鱼”,12日" University1 "));      var=组列表。GroupBy (m=比;新{m。年龄,m.Class});      foreach (var集团组)   {   控制台。WriteLine(“年龄:{0},类:{1}”,group.Key。年龄,group.Key.Class);   foreach (var的学生组)   {   Console.WriteLine(学生);   }   }   }      类学生   {   公共int Id{得到;设置;}   公共字符串名称{;设置;}   公共int年龄{得到;设置;}   公共字符串类{;设置;}      公开学生(int id字符串名称,int年龄,字符串@class)   {   Id=Id;   Name=名称;   年龄=年龄;   类=@class;   }      公共覆盖字符串ToString ()   {   返回$ " Id={Id},名称={名称},年龄={}时代,阶级={类}”;   }   }      类StudentKey   {   公共int年龄{得到;设置;}   公共字符串类{;设置;}   }   }      

<强>这时候输出结果是

  
  

年龄:10类:University1
  Id=1,名称=猫类==10岁University1
  Id=2,名称=狗类==10岁University1
  年龄:10类:University2
  Id=3、Name=猪类==10岁University2
  年龄:12类:University1
  Id=4, Name=鱼、类==12岁University1

     

将新{m。年龄,m。类}替换为新StudentKey{年龄=m。年龄、阶级=m.Class},结果却变成了

  
  

年龄:10类:University1
  Id=1,名称=猫类==10岁University1
  年龄:10类:University1
  Id=2,名称=狗类==10岁University1
  年龄:10类:University2
  Id=3、Name=猪类==10岁University2
  年龄:12类:University1
  Id=4, Name=鱼、类==12岁University1

     

Id=1和Id=2变成了两组。

  


  

  

解决问题方式有几种。

  

<强>第一种
  

  

最简单,就是直接将StudentKey从类变成结构。

c# GroupBy的基本使用教程