Если у меня есть две коллекции типа T и IEqualityComparer, который сравнивает подмножество их свойств, из какой коллекции будут получены результирующие элементы Intersect или Union?
Тесты, которые я провел до сих пор, предполагают следующее:
- предмет(ы) из col1 выигрывают
- если col1 или col2 содержат повторяющиеся элементы (как определено компаратором) внутри себя, выигрывает первая запись (внутри col1, затем col2).
Я знаю, что это не должно быть проблемой, поскольку (по определению) я должен рассматривать полученные объекты как равные. Мне просто пришло в голову, что использование Union с пользовательским компаратором может быть немного более аккуратным, чем эквивалентное соединение, хотя это справедливо только в том случае, если вышеуказанные предположения гарантированы.
class DummyComparer : IEqualityComparer<Dummy>
{
public bool Equals(Dummy x, Dummy y)
{
return x.ID == y.ID;
}
public int GetHashCode(Dummy obj)
{
return obj.ID.GetHashCode();
}
}
class Dummy
{
public int ID { get; set; }
public string Name { get; set; }
}
[Test]
public void UnionTest()
{
var comparer = new DummyComparer();
var d1 = new Dummy { ID = 0, Name = "test0" };
var d2 = new Dummy { ID = 0, Name = "test1" };
var d3 = new Dummy { ID = 1, Name = "test2" };
var d4 = new Dummy { ID = 1, Name = "test3" };
var col1 = new Dummy[] { d1, d3 };
var col2 = new Dummy[] { d2, d4 };
var x1 = col1.Union(col2, comparer).ToList();
var x2 = col2.Union(col1, comparer).ToList();
var y1 = col1.Except(col2, comparer).ToList();
var y2 = col2.Except(col1, comparer).ToList();
var z1 = col1.Intersect(col2, comparer).ToList();
var z2 = col2.Intersect(col1, comparer).ToList();
Assert.AreEqual(2, x1.Count);
Assert.Contains(d1, x1);
Assert.Contains(d3, x1);
Assert.AreEqual(2, x2.Count);
Assert.Contains(d2, x2);
Assert.Contains(d4, x2);
Assert.AreEqual(0, y1.Count);
Assert.AreEqual(0, y2.Count);
Assert.AreEqual(2, z1.Count);
Assert.Contains(d1, z1);
Assert.Contains(d3, z1);
Assert.AreEqual(2, z2.Count);
Assert.Contains(d2, z2);
Assert.Contains(d4, z2);
}
Intersect
. Можете проверить EduLinq, он подробно описывает оригинал реализации. - person Rawling   schedule 24.01.2014Intersect
с помощью ILSpy, и он сначала перечисляет вторую коллекцию, а затем первую, даже если документировано наоборот. Что может быть причиной? Изменить На самом деле Джон Скит также упомянул эту ложь: msmvps.com/blogs/jon_skeet/archive/2010/12/30/ (по его словам: Это очевидно неверно.) - person Tim Schmelter   schedule 24.01.2014Intersect
возвращаются - я читаю это как элементы меток во второй последовательности и возвращаю их, но вы явно читаете наоборот. (Да, это страница, о которой я думал, когда связывал EduLinq.) - person Rawling   schedule 24.01.2014