2017-01-02 37 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. 我不明白,第一個匿名類型,因爲從我的理解,一個匿名類型的格式應該是這樣的

    新{字段1 = x.Department,字段2 = x.Gender}

第一個匿名類型如何能沒有字段?我的意思是,這是正確的語法來寫這樣的事:

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

但會有,如果我把它寫這樣的編譯錯誤:

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

'field1'只有工作,沒有與常量值'field2'的領域。當你選擇你正在做一個匿名類型的投影的時候,當你'groupBy'你得到了一些不同的東西:IEnumerable >' – Crowcoder

+0

如果你省略了'field ='部分,那麼fieldname取自變量/屬性。見['匿名類型'](http://stackoverflow.com/documentation/c%23/765/anonymous-types/2612/creating-an-anonymous-type#t=201701021356107409379) – Nico

回答

15

匿名類型可以通過多個字段這裏使用的組,因爲GroupBy使用默認的相等比較器。
匿名類型的默認相等比較器對匿名類型的每個屬性使用默認的相等比較器。

因此對於第一個匿名類型,如果Department s和兩個Gender s都相等(根據它們的默認相等比較器),那麼兩個實例相等。

你可以想象匿名類型是類似的東西:(從x.DepartmentDepartmentx.GenderGender)編譯器使用屬性名作爲名稱:

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

第二個問題也很容易爲匿名類型的屬性。

所以

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

創建了一個名爲Department屬性和一個名爲Gender屬性類型。
當然,這可以與現有的性能/名稱,如

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

謝謝你的回答。十分清晰 – grooveline