From 39645bfe2980825509527917097f9acf8378b8ce Mon Sep 17 00:00:00 2001 From: Filip Strajnar Date: Sat, 11 May 2024 15:17:41 +0200 Subject: [PATCH] Implemented comparison of IEnumerables in RecursiveFieldsEqual. --- AioNet.Reflection/DeepComparison.cs | 51 ++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/AioNet.Reflection/DeepComparison.cs b/AioNet.Reflection/DeepComparison.cs index 5be99dd..2d41aef 100644 --- a/AioNet.Reflection/DeepComparison.cs +++ b/AioNet.Reflection/DeepComparison.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -36,7 +37,7 @@ namespace AioNet.Reflection // If type is IEnumerable, compare individual elements. if (type.GetInterface("System.Collections.IEnumerable") != null) { - throw new NotImplementedException(); + return RecursiveEnumerableEquals(first, second); } IEnumerable fields = type.GetRuntimeFields(); @@ -50,5 +51,53 @@ namespace AioNet.Reflection ); }); } + + private static bool RecursiveEnumerableEquals(T first, T second) + { + // Throwing exceptions if casting to System.Collections.IEnumerable doesn't work. + IEnumerator firstEnumerator = ((IEnumerable)first).GetEnumerator(); + IEnumerator secondEnumerator = ((IEnumerable)second).GetEnumerator(); + + while (firstEnumerator.MoveNext()) + { + // If the second enumerator doesn't advance when first does, + // this means that first enumerator has more elements, so they + // can't be equal. + if (!secondEnumerator.MoveNext()) + { + return false; + } + + Type firstType = firstEnumerator.Current.GetType(); + Type secondType = secondEnumerator.Current.GetType(); + + // If types don't match, they can't be equal. + if (!(firstType == secondType)) + { + return false; + } + + bool elementsEqual = RecursiveFieldsEqual( + firstEnumerator.Current, + secondEnumerator.Current, + firstType + ); + // If the two elements are not equal, then the entire enumerable is not equal. + if (!elementsEqual) + { + return false; + } + } + + // If second enumerator can move even though first can't, it's + // longer and therefore the two are not equal. + if (secondEnumerator.MoveNext()) + { + return false; + } + + // If there were no differences found, we return true. + return true; + } } }