通过在Linq中使用匿名类型进行分组

gro*_*ine 9 .net c# linq

假设我有一个Employee类,GetAllEmployees()返回一个employee实例列表.我想按部门和性别对员工进行分组,所以答案就是

var employeeGroup = Employee.GetAllEmployees()
                            .GroupBy(x => new { x.Department, x.Gender }) // I don't understand this anonymous type
                            .OrderBy(g => g.Key.Department)
                            .ThenBy(g => g.Key.Gender)
                            .Select(g => new {   //I can understand this anonymous type
                               Dept = g.Key.Department,
                               Gender = g.Key.Gender,
                               Employees = g.OrderBy(x => x.Name)
                             });
Run Code Online (Sandbox Code Playgroud)

我有两个问题:

  1. 为什么匿名类型允许多个密钥组?

  2. 我不明白第一个匿名类型,因为根据我的理解,匿名类型的格式应该是这样的

    new {field1 = x.Department,field2 = x.Gender}

为什么第一个匿名类型没有字段?我的意思是,写这样的东西是正确的语法:

var anonymous = new {field1 = 1,field2 =2}
Run Code Online (Sandbox Code Playgroud)

但如果我像这样写它会有编译错误:

var anonymous = new {1, 2} //compile error !!!
Run Code Online (Sandbox Code Playgroud)

Ren*_*ogt 19

这里可以使用匿名类型按多个字段进行分组,因为GroupBy使用默认的相等比较器.
匿名类型的默认相等比较器对匿名类型的每个属性使用默认的相等比较器.

因此对于第一个匿名类型,如果Departments和两个Genders都相等(根据它们的默认相等比较器),则两个实例是相等的.

您可以想象匿名类型是这样的:

public class AnonymousType1
{
    public int Department { get; set; } // I don't know your department type
    public int Gender { get; set; } // neither your gender type

    public int GetHashCode() { return Department.GetHashCode() ^ Gender.GetHashCode(); }
    public bool Equals(AnonymousType1 other)
    {
        if (ReferenceEquals(other, null)) return false;
        return Department == other.Department && Gender == other.Gender;
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个问题也很简单:编译器使用属性名称(Departmentfrom x.DepartmentGenderfrom x.Gender)作为匿名类型属性的名称.

所以

var anon = new { employee.Department, employee.Gender }
Run Code Online (Sandbox Code Playgroud)

创建一个带有被调用属性Department和被调用属性的类型Gender.
当然,这只适用于现有的属性/名称,而不是像常量值那样

var anon = new {1,2}; // fails to compile, no names provided.
Run Code Online (Sandbox Code Playgroud)