C#与IEnumerable <T>不同的自定义IEqualityComparer

这是我想要做的。 我正在使用LINQ to XML查询XML文件,这给了我一个IEnumerable <T >对象,其中T是我的“Village”类,充满了这个查询的结果。 一些结果是重复的,所以我想对IEnumerable对象执行Distinct(),就像这样:

 public IEnumerable<Village> GetAllAlliances() { try { IEnumerable<Village> alliances = from alliance in xmlDoc.Elements("Village") where alliance.Element("AllianceName").Value != String.Empty orderby alliance.Element("AllianceName").Value select new Village { AllianceName = alliance.Element("AllianceName").Value }; // TODO: make it work... return alliances.Distinct(new AllianceComparer()); } catch (Exception ex) { throw new Exception("GetAllAlliances", ex); } } 

由于缺省比较器不适用于Village对象,因此我实现了一个自定义比较器,如在AllianceComparer类中所示:

 public class AllianceComparer : IEqualityComparer<Village> { #region IEqualityComparer<Village> Members bool IEqualityComparer<Village>.Equals(Village x, Village y) { // Check whether the compared objects reference the same data. if (Object.ReferenceEquals(x, y)) return true; // Check whether any of the compared objects is null. if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; return x.AllianceName == y.AllianceName; } int IEqualityComparer<Village>.GetHashCode(Village obj) { return obj.GetHashCode(); } #endregion } 

Distinct()方法不起作用,因为我有完全相同数量的结果,有或没有它。 另一件事,我不知道是否通常是可能的,但我不能进入AllianceComparer.Equals()看看有什么问题。
我在互联网上find了这样的例子,但我似乎无法使我的实施工作。

希望这里有人可能会看到这里可能是错的! 提前致谢!

问题是你的GetHashCode 。 您应该改变它来返回AllianceName的哈希代码。

 int IEqualityComparer<Village>.GetHashCode(Village obj) { return obj.AllianceName.GetHashCode(); } 

问题是,如果Equals返回true ,则对象应该具有相同的散列码,而对于具有相同AllianceName不同Village对象则不同。 由于Distinct通过在内部构build一个哈希表来工作,所以最终会得到相同的对象,由于不同的哈希码,这些对象根本不会匹配。

同样,为了比较两个文件,如果两个文件的散列值不相同,则根本不需要检查文件本身。 他们有所不同。 否则,你会继续检查是否真的是一样的。 这正是Distinct使用的哈希表的行为。

return alliances.Select(v => v.AllianceName).Distinct();

这将返回一个IEnumerable<string>而不是IEnumerable<Village>

或者改变线路

 return alliances.Distinct(new AllianceComparer()); 

 return alliances.Select(v => v.AllianceName).Distinct(); 
Interesting Posts