2017-01-02 17 views
7

Giả sử tôi có một lớp Nhân viên và GetAllEmployees() trả về một danh sách cá thể của nhân viên. Tôi muốn nhân viên nhóm do Sở và giới tính, vì vậy câu trả lời tôi có lànhóm bằng cách sử dụng loại ẩn danh trong 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) 
          }); 

Tôi có hai câu hỏi:

  1. Tại sao một loại vô danh cho phép một nhóm nhiều phím bằng?

  2. Tôi không hiểu các loại vô danh đầu tiên, bởi vì từ hiểu biết của tôi, định dạng một loại vô danh nên được như thế này

    mới {field1 = x.Department, field2 = x.Gender}

Làm cách nào để loại ẩn danh đầu tiên có thể có mà không có trường? Ý tôi là, đó là cú pháp chính xác để viết một cái gì đó như thế này:

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

Nhưng sẽ có biên dịch lỗi nếu tôi viết nó như thế này:

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

'field1' và' field2' là các lĩnh vực. Khi bạn 'select' bạn đang thực hiện phép chiếu thành một kiểu ẩn danh, khi bạn' groupBy' bạn đang nhận được một cái gì đó khác: 'IEnumerable >' – Crowcoder

+0

Nếu bạn bỏ qua phần 'field =', tên trường được lấy từ biến/thuộc tính. Xem ['anonymous types'] (http://stackoverflow.com/documentation/c%23/765/anonymous-types/2612/creating-an-anonymous-type#t=201701021356107409379) – Nico

Trả lời

15

loại Anonymous có thể được sử dụng ở đây vào nhóm bởi nhiều lĩnh vực , bởi vì GroupBy sử dụng trình so sánh bình đẳng mặc định.
Trình so sánh bình đẳng mặc định cho các loại ẩn danh sử dụng trình so sánh bình đẳng mặc định cho mỗi thuộc tính của loại ẩn danh.

Vì vậy, đối với loại ẩn danh đầu tiên, hai trường hợp bằng nhau nếu cả hai Department s và cả hai Gender s đều bằng nhau (theo các trình so sánh bình đẳng mặc định của chúng).

Bạn có thể tưởng tượng kiểu nặc danh là một cái gì đó như thế:

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

Câu hỏi thứ hai là dễ dàng, quá: Trình biên dịch sử dụng tên tài sản (Department từ x.DepartmentGender từ x.Gender) như tên cho các thuộc tính của kiểu ẩn danh.

Vì vậy

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

tạo ra một kiểu với một tài sản gọi là Department và một tính chất gọi Gender.
Tất nhiên điều này chỉ có thể làm việc với hiện tính/tên, không phải với giá trị không đổi như

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

Cảm ơn câu trả lời của bạn. Rất rõ ràng – grooveline

Các vấn đề liên quan