2017-01-02 5 views
7

Скажем, у меня есть класс Employee, а GetAllEmployees() возвращает список экземпляра сотрудника. Я хочу, чтобы сотрудники группы по отделам и гендерным вопросам, поэтому ответ у меня естьгруппа с использованием анонимного типа в Linq

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) 
          }); 

У меня есть два вопроса:

  1. Почему анонимный тип позволяет группе несколько ключей от?

  2. Я не понимаю, первый анонимный тип, потому что от моего понимания, формат анонимного типа должно быть, как это

    новый {field1 = x.Department, field2 = x.Gender}

Почему первый анонимный тип может иметь без полей? Я имею в виду, это правильный синтаксис, чтобы написать что-то вроде этого:

var anonymous = new {field1 = 1,field2 =2} 

Но будет ошибка компиляции, если я пишу это так:

var anonymous = new {1, 2} //compile error !!! 
+0

'field1' и' field2' являются полями. Когда вы выбираете 'вы делаете проекцию в анонимный тип, когда вы' groupBy', вы получаете что-то другое: 'IEnumerable >' – Crowcoder

+0

Если вы опустите часть 'field =', имя поля берется из свойства переменной /. См. ['Анонимные типы'] (http://stackoverflow.com/documentation/c%23/765/anonymous-types/2612/creating-an-anonymous-type#t=201701021356107409379) – Nico

ответ

15

Анонимные типы могут быть использованы здесь, чтобы сгруппировать по нескольким полям , потому что GroupBy использует сопоставитель равенства по умолчанию.
По умолчанию для сопоставления равенства для анонимных типов используется сопоставитель равенства по умолчанию для каждого свойства анонимного типа.

Таким образом, для первого анонимного типа два экземпляра равны, если оба значения Department s и оба значения Gender s равны (в соответствии с их сравнениями равенства по умолчанию).

Вы можете представить себе анонимный тип нечто подобное:

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; 
    } 
} 

Второй вопрос тоже очень легко: Компилятор использует имена свойств (Department от x.Department и Gender от x.Gender) в качестве имен для свойств анонимного типа.

Так

var anon = new { employee.Department, employee.Gender } 

создает тип со свойством называется Department и свойство называется Gender.
Конечно, это может работать только с существующими свойствами/именами, а не с постоянными значениями, как

var anon = new {1,2}; // fails to compile, no names provided. 
+0

Благодарим вас за ответ. Так ясно – grooveline

Смежные вопросы