2011-11-04 26 views
6

Tôi gặp sự cố khi tôi muốn loại nhóm được đánh máy mạnh nhưng nếu tôi không nhóm đúng cách. Xem mã dưới đây ...Tại sao sử dụng loại công việc ẩn danh và sử dụng loại rõ ràng không có trong GroupBy?

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication35 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Foo> foos = new List<Foo>(); 
      foos.Add(new Foo() { Key = "Test" }); 
      foos.Add(new Foo() { Key = "Test" }); 
      foos.Add(new Foo() { Key = "Test" }); 

      var groups = foos.GroupBy<Foo, dynamic>(entry => new 
      { 
       GroupKey = entry.Key 
      }); 

      Console.WriteLine(groups.Count()); 

      groups = foos.GroupBy<Foo, dynamic>(entry => new GroupingKey() 
      { 
       GroupKey = entry.Key 
      }); 

      Console.WriteLine(groups.Count()); 

     } 

     public class Foo 
     { 
      public string Key { get; set; } 
     } 

     public class GroupingKey 
     { 
      public string GroupKey { get; set; } 
     } 
    } 
} 

Sản lượng:

1 
3 
Press any key to continue . . . 

Tôi mong chờ kết quả là như nhau bất kể sử dụng một loại rõ ràng và cũng không không có nghĩa là chỉ nên là một nhóm với 3 mục không phải 3 nhóm với 1 mục. Chuyện gì đang xảy ra ở đây?

Cập nhật tôi đã thêm một IEqualityComparer và nó hoạt động bây giờ! Xem dưới đây:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication35 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Foo> foos = new List<Foo>(); 
      foos.Add(new Foo() { Key = "Test" }); 
      foos.Add(new Foo() { Key = "Test" }); 
      foos.Add(new Foo() { Key = "Test" }); 

      var groups = foos.GroupBy<Foo, dynamic>(entry => new //GroupingKey() 
      { 
       GroupKey = entry.Key 
      }); 

      Console.WriteLine(groups.Count()); 

      groups = foos.GroupBy<Foo, GroupingKey>(entry => new GroupingKey() 
      { 
       GroupKey = entry.Key 
      }, new GroupingKeyEqualityComparer()); 

      Console.WriteLine(groups.Count()); 

     } 

     public class Foo 
     { 
      public string Key { get; set; } 
     } 

     public class GroupingKey 
     { 
      public string GroupKey { get; set; }    
     } 

     public class GroupingKeyEqualityComparer : IEqualityComparer<GroupingKey> 
     { 
      #region IEqualityComparer<GroupingKey> Members 

      public bool Equals(GroupingKey x, GroupingKey y) 
      { 
       return x.GroupKey == y.GroupKey; 
      } 

      public int GetHashCode(GroupingKey obj) 
      { 
       return obj.GroupKey.GetHashCode(); 
      } 

      #endregion 
     } 
    } 
} 

Output:

1 
1 
Press any key to continue . . . 

này khá nhiều khẳng định câu trả lời được đưa ra bởi JaredPar!

+0

Ứng dụng có hoạt động nếu bạn thay đổi 'nhóm' thứ hai thành tên biến khác và thay vì sử dụng '' sử dụng ''? Có thể ngắt kết nối là kiểu gõ chung trong trường hợp này. –

+0

@ Jelel - thực sự là điều năng động dường như không tạo ra sự khác biệt cho đến khi tôi thêm IEqualityComparer và nó buộc tôi phải thay đổi nó để các loại liên kết. – Jim

Trả lời

7

Trong phiên bản đầu tiên, bạn đang tạo loại ẩn danh với một thuộc tính duy nhất có tên là GroupKey. Các kiểu ẩn danh trong C# sử dụng sự bình đẳng về cấu trúc nên sự bình đẳng của các giá trị đi xuống đến sự bình đẳng của các khóa. Điều này khiến chúng được nhóm lại với nhau một cách chính xác.

Trong trường hợp thứ hai, bạn đang sử dụng loại tùy chỉnh có tên là GroupingKey. Nó xuất hiện này sử dụng bình đẳng mặc định hoặc tham chiếu. Do đó không có trường hợp nào được coi là bình đẳng và do đó chúng được đưa vào các nhóm khác nhau.

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