2011-11-04 36 views
6

Bir grup yazısının güçlü bir şekilde yazılmasını istediğim bir sorun var, ancak yaparsam doğru şekilde gruplanmadı. Ben yani ne olursa olsun açık bir türü kullanmanın ne de sonuç aynı olmasını beklediğinizNiçin anonim tür kullanıyor ve GroupBy'de açık bir tür kullanmıyorsunuz?

1 
3 
Press any key to continue . . . 

sadece 3 öğelerle bir grup olmalıdır:

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

çıktı ... Aşağıdaki kod bakın 1 öğe ile 3 grup değil. Burada neler oluyor?

Güncelleme Bir IEqualityComparer eklendi ve şimdi çalışıyor! Aşağıya bakın:

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

Çıktı:

1 
1 
Press any key to continue . . . 

Bu hemen hemen JaredPar verdiği cevabı onaylar!

+0

İkinci "grupları" farklı bir değişken adına değiştirirseniz ve kullanmak yerine 'işlevini kullanır mı? Bağlantı kesmenin bu örnekte genel yazım olması mümkündür. –

+0

@Joel - aslında dinamik bir şey IEqualityComparer'ı ekledikten sonra bir değişiklik yapmıyor gibi görünüyordu ve beni değiştirmeye zorladım. – Jim

cevap

7

İlk sürümde, GroupKey adlı tek bir özelliğe sahip anonim bir tür oluşturuyorsunuz. C# içindeki anonim tipler yapısal eşitliği kullanır, böylece değerlerin eşitliği anahtarların eşitliğine gelir. Bu onların birlikte düzgün bir şekilde gruplandırılmasına neden olur.

İkinci durumda, GroupingKey adında özel bir tür kullanıyorsunuz. Görünüşe göre bu varsayılan veya referans eşitliğini kullanır. Bu nedenle, örneklerin hiçbiri eşit kabul edilmez ve dolayısıyla farklı gruplara alınırlar.