/// <summary> /// Compares the specified object graphs. It is called by <see cref="ObjectGraphComparer"/>. /// </summary> /// <param name="left">The left.</param> /// <param name="right">The right.</param> /// <param name="comparer"> /// The calling comparer to compare object sub-graphs, which the given strategy does /// not work with and perform other interactions. /// </param> /// <returns> /// <c>true</c> if the specified nodes are equal; otherwise, <c>false</c>. /// </returns> internal bool Compare(GraphNode left, GraphNode right, ObjectGraphComparer comparer) { Debug.Assert(left != null); Debug.Assert(right != null); Debug.Assert(comparer != null); EnterCompare(comparer); try { var mismatches = Compare(left, right); if (mismatches != null) { ComparisonResult &= !mismatches.Any(); foreach (var m in mismatches) { Comparer.AddMismatch(m); } } return(ComparisonResult); } finally { ExitCompare(); } }
public ComparerResultTuple(ObjectGraphComparer comparer) { Comparer = comparer; ComparisonResult = true; }
private void EnterCompare(ObjectGraphComparer comparer) { comparisons.Push(new ComparerResultTuple(comparer)); }
/// <summary> /// Performs and unordered comparison of the given object graph collections. /// </summary> /// <param name="leftNodes">The left nodes.</param> /// <param name="rightNodes">The right nodes.</param> private bool CompareObjectGraphs(IEnumerable <GraphNode> leftNodes, IEnumerable <GraphNode> rightNodes) { var left = leftNodes.ToList(); var right = rightNodes.ToList(); if (left.Count == 1 && right.Count == 1) { return(CompareObjectGraphs(left.First(), right.First())); } var mismatchesCount = m_mismatches.Count; // One of the groups has more than 1 element, since we are // doing unordered comparison by default, we need to // go through elements in both groups and find matches var leftIndex = 0; while (leftIndex < left.Count) { var found = false; for (int rightIndex = 0; rightIndex < right.Count; rightIndex++) { if (m_probing) { // If we are already in the probing mode, there is no need to // create a yet new comparer found = CompareObjectGraphs(left[leftIndex], right[rightIndex]); if (!found) { return(false); } } else { var probingComparer = new ObjectGraphComparer(m_visited); found = probingComparer.CompareObjectGraphs(left[leftIndex], right[rightIndex]); // If nodes match, need to remember visited sub-nodes if (found) { m_visited.UnionWith(probingComparer.m_visited); } } if (found) { left.RemoveAt(leftIndex); right.RemoveAt(rightIndex); break; } } if (!found) { leftIndex++; } } // Now left and right contain elements without a match // Go through them and get mismatches... while (left.Any() && right.Any()) { // ...but, if we are just probing for equality of nodes, we already // know the answer if (m_probing) { return(false); } CompareObjectGraphs(left.First(), right.First()); left.RemoveAt(0); right.RemoveAt(0); } if (left.Any() || right.Any()) { // If we are just probing for equality of nodes, we already // know the answer if (m_probing) { return(false); } AddMissingNodeMismatches(left, true); AddMissingNodeMismatches(right, false); } return(m_mismatches.Count == mismatchesCount); }