これが私がやろうとしていることです。 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()に足を踏み入れて、何が問題になるのかを知ることはできません。
インターネットでこの例を見つけましたが、実装を機能させることができません。
うまくいけば、ここの誰かがここで何が間違っているのかを見るかもしれません!前もって感謝します!
問題はGetHashCode
にあります。代わりにAllianceName
のハッシュコードを返すように変更する必要があります。
int IEqualityComparer<Village>.GetHashCode(Village obj)
{
return obj.AllianceName.GetHashCode();
}
問題は、Equals
がtrue
を返す場合、オブジェクトは同じVillage
を持つ異なるAllianceName
オブジェクトの場合ではない同じハッシュコードを持つ必要があります。 Distinct
はハッシュテーブルを内部で構築することで機能するため、ハッシュコードが異なるために一致しないオブジェクトが同じになることになります。
同様に、2つのファイルを比較するために、2つのファイルのハッシュが同じでない場合、ファイル自体をチェックする必要はまったくありません。彼ら 意志 異なる。それ以外の場合は、それらが本当に同じであるかどうかを確認し続けます。それが、Distinct
が使用するハッシュテーブルの動作です。
return alliances.Select(v => v.AllianceName).Distinct();
それはIEnumerable<string>
ではなくIEnumerable<Village>
を返します。
または、行を変更します
return alliances.Distinct(new AllianceComparer());
に
return alliances.Select(v => v.AllianceName).Distinct();