IEqualityComparer с Linq to XML и Distinct() не выполняется в коде?

#c# #xml #linq #distinct #iequalitycomparer

#c# #xml #linq #distinct #iequalitycomparer

Вопрос:

Не имеет значения, что я пишу в методе Equals . GetHashCode всегда запускается, но я не знаю, чей GetHashCode возвращать?

Когда вызывается метод GetHashCode, переменная x содержит следующие данные:

В первом имя_элемента имя_элемента — это значение «Это значение, которое я хочу сравнить» …

 <unit>
  <unitName>This is the value I want to compare</unitName>
  <units>
    <unit>
      <unitName>xxx</unitName>      
      <units>
        <unit>
          <unitName>cccc</unitName>
          <test>33</test>
          <test>44</test>                   
        </unit>
      </units>          
        </unit>
    </units>        
</unit>
  
 IEnumerable<XElement> tempMemberList = doc.Elements("dep").Descendants("customers").Distinct(new XElementComparer());

public class XElementComparer : IEqualityComparer<XElement> {
    public bool Equals(XElement x, XElement y) {

        return x.Value == y.Value;
    }

    public int GetHashCode(XElement x) {
        return x.GetHashCode();
    }
}
  

Ответ №1:

Было бы разумно вернуть хэш-код Value элемента, поскольку вы используете его для определения равенства. Ваша GetHashCode() реализация должна соответствовать вашей Equals() реализации.

 public class XElementComparer : IEqualityComparer<XElement> {
    public bool Equals(XElement x, XElement y) {
        return x.Value == y.Value;
    }

    public int GetHashCode(XElement x) {
        return x.Value.GetHashCode();
    }
}
  

Комментарии:

1. ps, ваш запрос фактически не выдает никаких элементов. В вашем опубликованном XML нет никаких dep элементов и нет customers элементов.

2. Ну, конечно, это нормально, но если вы собираетесь менять имена, вы должны быть последовательными и изменять все его использование, чтобы ничего не нарушать. 😉

3. Поскольку вы знали мою структуру xml, вам следовало использовать «UnitName» 🙂

Ответ №2:

Это решение, мне просто нужно было получить правильное значение из первого имени объекта, которое я хотел…

 public class XElementComparer : IEqualityComparer<XElement>
        {
            public bool Equals(XElement x, XElement y)
            {
                string unitNameX = x.Element("unitName ").Value;
                string unitNameY = y.Element("unitName ").Value;
                return unitNameX == unitName Y;
            }

            public int GetHashCode(XElement x)
            {
                string val = x.Element("unitName ").Value;
                return val.GetHashCode();
            }
        }
  

Ответ №3:

Вы также можете написать что-то, что будет работать для большей части xml.

 public class XElementComparer : IEqualityComparer<XElement>
{
    public bool Equals(XElement x, XElement y) 
    {
        return (x.FirstAttribute.Value.Equals(y.FirstAttribute.Value) 
                amp;amp; x.LastAttribute.Value.Equals(y.LastAttribute.Value)); 
    } 

    public int GetHashCode(XElement x) 
    { 
        return x.Value.GetHashCode(); 
    }
}