Если у меня есть:
IEnumerable<CrewBase> crewBasesLeft;
IEnumerable<CrewBase> crewBasesRight;
и выполните:
IEnumerable<CrewBase> intersect = crewBasesLeft
.Intersect( crewBasesRight,CrewBaseComparer.OnId() );
Как мне получить:
CrewBase left;
CrewBase right;
:
intersect
поэтому я могу перебрать все CrewBases в Intersect и сделать вызов:
Action(left,right);
Я только хочу сделать это на CrewBases, которые равны в обоих списках в соответствии с моим CrewBaseComparer.OnId, который реализует:
IEqualityComparer<CrewBase>
Это моя текущая реализация:
IEnumerable<ObjectDifference> GetCrewBaseDifferences2( TrafficPlan left, TrafficPlan right )
{
var result = new List<ObjectDifference>();
IEnumerable<CrewBase> intersect = left.CrewBases.Intersect( right.CrewBases,CrewBaseComparer.OnId() );
foreach( CrewBase crewBase in intersect )
{
CrewBase other = crewBase;
ObjectDifference diff = crewBase.GetDifference( right.CrewBases.First(x => x.Equals(other, CrewBaseComparer.OnId())) );
if( diff.HasDifferences )
{
result.Add( diff );
}
}
return result;
}
Вам нужно будет определить класс, который реализует IEqualityComparer:
class CustomComparer : IEqualityComparer<CrewBase>
{
#region IEqualityComparer<CrewBase> Members
public bool Equals(CrewBase x, CrewBase y)
{
return CustomCompare(x, y);
}
public int GetHashCode(CrewBase obj)
{
//a hash code based on the specific comparison
}
#endregion
}
а затем вызовите Intersect с экземпляром вашего класса:
IEnumerable<CrewBase> intersect = crewBasesLeft.Intersect(crewBasesRight, new CustomComparer());
Не обязательно, чтобы Intersect всегда передавал элемент из "left" и элемент из "right" в качестве параметров "x" и "y" соответственно, но это не ясно из вашего вопроса, если это имеет значение.
Основываясь на вашем обновлении, похоже, что вам нужно сделать Join:
IEnumerable<CrewBase> crewBasesLeft;
IEnumerable<CrewBase> crewBasesRight;
var Join = crewBasesLeft.Join(crewBasesRight, left => left, right => right, (left, right) => new { left, right }, CrewBaseComparer.OnId());
foreach (var i in Join)
{
Action(i.left, i.right);
}
В этом соединении мы рассматриваем каждый элемент как ключ и используем существующий пользовательский IEqualityComparer для сравнения экземпляров. Селектор результатов для соединения возвращает анонимный тип со свойствами "left" и "right", соответствующими элементам из левой и правой коллекций. Затем вы можете перебрать результат, чтобы выполнить свое действие.
Я думаю, что у вас может быть неправильное представление о пересечении. Если вы берете пересечение двух списков, как кажется, что вы делаете, результатом будет один список, содержащий все элементы, которые находятся в обоих списках.
Таким образом, как только вы сделали
IEnumerable<CrewBase> crewBasesLeft;
IEnumerable<CrewBase> crewBasesRight;
IEnumerable<CrewBase> intersect = crewBasesLeft.Intersect( crewBasesRight,CrewBaseComparer.OnId() );
IEnumerable в пересечении не нуждается в левом или правом.
Однако, если то, что вы пытаетесь сделать, это получить влево и вправо в вашем пользовательском IEqualityComparer, тогда вы хотите, чтобы объект выглядел примерно так:
class CrewBaseIdComparer : IEqualityComparer<CrewBase>
{
public bool Equals(CrewBase left, CrewBase right)
{
// your logic
}
public int GetHashCode(CrewBase item)
{
// your logic
}
}