Использование Linq, кроме того, что я не работаю, как я думал
List1 содержит элементы {A, B} и List2 содержит элементы {A, B, C}.
Мне нужно вернуть {C}, когда я использую Extension Linq extension. Вместо этого я возвращаюсь {A, B}, и если я переворачиваю списки в моем выражении, результат получается {A, B, C}.
Неужели я не понимаю смысл Исключения? Есть ли другое расширение, которое я не вижу?
Я просмотрел и пробовал несколько разных сообщений по этому вопросу без успеха до сих пор.
var except = List1.Except(List2); //This is the line I have thus far
EDIT: Да, я сравнивал простые объекты. Я никогда не использовал IEqualityComparer, было интересно узнать об этом.
Спасибо всем за помощь. Проблема заключалась не в применении компаратора. Связанное сообщение в блоге и пример ниже, где полезно.
Ответы
Ответ 1
Если вы сохраняете ссылочные типы в своем списке, вы должны убедиться, что есть способ сравнить объекты для равенства. В противном случае они будут проверяться путем сравнения, если они ссылаются на один и тот же адрес.
Вы можете реализовать IEqualityComparer<T>
и отправить его в качестве параметра в Except(). Здесь вы можете найти сообщение в блоге.
Ответ 2
Вы просто путаете порядок аргументов. Я вижу, где эта путаница возникла, потому что официальная документация не так полезна, как может быть:
Производит заданное различие двух последовательностей с помощью сравнения по умолчанию для сравнения значений.
Если вы не разбираетесь в теории множеств, может быть неясно, что именно установить разницу на самом деле - это не просто то, что отличается между наборами. В действительности Except
возвращает список элементов в первом наборе, которые не находятся во втором наборе.
Попробуйте следующее:
var except = List2.Except(List1); // { C }
Ответ 3
Итак, просто для полноты...
// Except gives you the items in the first set but not the second
var InList1ButNotList2 = List1.Except(List2);
var InList2ButNotList1 = List2.Except(List1);
// Intersect gives you the items that are common to both lists
var InBothLists = List1.Intersect(List2);
Изменить: поскольку в ваших списках содержатся объекты, которые необходимо передать в IEqualityComparer для вашего класса... Вот что вы, кроме как будет выглядеть с образцом IEqualityComparer на основе созданных объектов...:)
// Except gives you the items in the first set but not the second
var equalityComparer = new MyClassEqualityComparer();
var InList1ButNotList2 = List1.Except(List2, equalityComparer);
var InList2ButNotList1 = List2.Except(List1, equalityComparer);
// Intersect gives you the items that are common to both lists
var InBothLists = List1.Intersect(List2);
public class MyClass
{
public int i;
public int j;
}
class MyClassEqualityComparer : IEqualityComparer<MyClass>
{
public bool Equals(MyClass x, MyClass y)
{
return x.i == y.i &&
x.j == y.j;
}
public int GetHashCode(MyClass obj)
{
unchecked
{
if (obj == null)
return 0;
int hashCode = obj.i.GetHashCode();
hashCode = (hashCode * 397) ^ obj.i.GetHashCode();
return hashCode;
}
}
}