一、先准备要使用的类:
1、Person类:
class Person
{
public string Name { set; get; }
public int Age { set; get; }
public string Gender { set; get; }
public override string ToString() => Name;
}
2、准备要使用的List,用于分组(GroupBy):
List<Person> personList = new List<Person>
{
new Person
在C#中,LINQ(Language Integrated Query,语言集成查询)提供了一种强大的方式来处理数据,其中`GroupBy`方法是用于对数据进行分类和分组的关键操作。本篇文章将详细探讨如何在C#中使用`GroupBy`,以及它的两种主要用法。
我们创建一个`Person`类,包含姓名`Name`、年龄`Age`和性别`Gender`这三个属性。这个类是用于演示`GroupBy`方法的实例。接着,我们创建一个`Person`对象的列表`personList`,并填充一些数据。
**第一种用法**:
`GroupBy`方法的基本形式如下:
```csharp
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
```
这个方法接收一个`source`(需要分组的序列)和一个`keySelector`(用于获取每个元素的分组键的委托)。在这个例子中,`keySelector`是一个从`Person`对象中提取`Gender`属性的函数,所以我们将根据每个人的性别进行分组。调用`GroupBy`后,我们得到一个`IEnumerable<IGrouping<TKey, TSource>>`的集合,其中`TKey`是分组键的类型(这里是`string`,对应于`Gender`),`TSource`是源序列元素的类型(这里是`Person`)。通过遍历这些分组,我们可以获取每个分组的键(性别)以及该组内的所有`Person`对象。
以下是对应的C#代码实现,它将按照性别打印出每个人的信息:
```csharp
var groups = personList.GroupBy(p => p.Gender);
foreach (var group in groups)
{
Console.WriteLine(group.Key);
foreach (var person in group)
{
Console.WriteLine($"\t{person.Name},{person.Age}");
}
}
```
这个操作等价于以下的LINQ查询表达式:
```csharp
var groups = from p in personList
group p by p.Gender;
```
**第二种用法**:
`GroupBy`还有另一个重载版本,用于指定自定义的键比较器:
```csharp
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer);
```
这个版本允许我们在键是自定义类型时,提供一个`IEqualityComparer`实例来决定键是否相等。在某些情况下,例如当我们需要根据`Person`对象的名称进行分组,但名称可能包含大小写差异时,这个功能就非常有用。
假设我们的`personList`现在包含两个名为"P1"的人,但年龄不同,我们需要忽略大小写进行分组。这时,我们需要创建一个自定义的`IEqualityComparer<string>`,然后在`GroupBy`调用中使用它。但是,对于简单的字符串比较,C#默认的`StringComparer.OrdinalIgnoreCase`就已经足够了。
以下是修改后的`personList`和使用自定义比较器的`GroupBy`示例:
```csharp
List<Person> personList = new List<Person>
{
new Person { Name = "P1", Age = 18, Gender = "Male" },
new Person { Name = "P1", Age = 19, Gender = "Male" },
new Person { Name = "P3", Age = 17, Gender = "Female" }
};
var groups = personList.GroupBy(p => p.Name, StringComparer.OrdinalIgnoreCase);
```
这样,即使名字的大小写不一致,"P1"也会被正确地归为同一组。
C#的`GroupBy`方法是LINQ中极其重要的一个部分,它为我们提供了灵活的数据组织方式,可以根据各种标准对数据进行分组和聚合。无论是基于简单的属性值,还是自定义的比较逻辑,`GroupBy`都能满足我们在处理数据时的多种需求。