C# IENUMERABLE 에 대해 CUSTAL IEQUILITY COMPARER로 구별
-
10-07-2019 - |
문제
여기 내가하려는 일이 있습니다. LINQ에서 XML을 사용하여 XML 파일을 쿼리하고 있습니다.<T
> 대상, 여기서 t는 내 "마을"클래스 이며이 쿼리의 결과로 가득 차 있습니다. 일부 결과는 복제되므로 다음과 같이 ienumerable 객체에서 별개의 ()를 수행하고 싶습니다.
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);
}
}
기본 비교가 마을 대상에 대해 작동하지 않기 때문에 Alliancomparer 클래스에서 볼 수 있듯이 사용자 정의를 구현했습니다.
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
}
정확히 같은 수의 결과가 있거나없는 결과가 없으므로 별개의 () 메소드가 작동하지 않습니다. 또 다른 것은, 그리고 그것이 일반적으로 가능한지 모르겠지만, AllianceComparer.equals ()에 들어가 문제가 무엇인지 확인할 수는 없습니다.
인터넷에서 이것의 예를 찾았지만 구현이 작동하지 않는 것 같습니다.
바라건대, 여기 누군가가 여기에서 무엇이 잘못 될 수 있는지 볼 수 있기를 바랍니다! 미리 감사드립니다!
해결책
문제는 당신의 것입니다 GetHashCode
. 해시 코드를 반환하도록 변경해야합니다. AllianceName
대신에.
int IEqualityComparer<Village>.GetHashCode(Village obj)
{
return obj.AllianceName.GetHashCode();
}
문제는 if입니다 Equals
보고 true
, 객체에는 다른 해시 코드가 있어야합니다. Village
동일 한 개체 AllianceName
. 부터 Distinct
내부적으로 해시 테이블을 구축하여 작동하면 해시 코드가 다른 동일한 개체가 전혀 일치하지 않습니다.
마찬가지로 두 파일을 비교하려면 두 파일의 해시가 동일하지 않은 경우 파일을 전혀 확인할 필요가 없습니다. 그들 ~ 할 것이다 다르게하십시오. 그렇지 않으면, 당신은 그들이 실제로 동일인지 아닌지 계속 확인할 것입니다. 그것이 바로 해시 테이블입니다 Distinct
동작을 사용합니다.
다른 팁
return alliances.Select(v => v.AllianceName).Distinct();
그것은 반환 할 것입니다 IEnumerable<string>
대신에 IEnumerable<Village>
.
또는 선을 변경하십시오
return alliances.Distinct(new AllianceComparer());
에게
return alliances.Select(v => v.AllianceName).Distinct();