diff --git a/src/Comparation/CompositeEquality.cs b/src/Comparation/CompositeEquality.cs index 3e6c832..5afe18e 100644 --- a/src/Comparation/CompositeEquality.cs +++ b/src/Comparation/CompositeEquality.cs @@ -1,20 +1,23 @@ -using System.Collections.Generic; +#if !NETSTANDARD2_0 +using System; +#endif +using System.Collections.Generic; using System.Linq; namespace Comparation { public sealed class CompositeEquality : IEqualityComparer { - private readonly IReadOnlyCollection> aspects; + private readonly IEqualityComparer[] aspects; public CompositeEquality(params IEqualityComparer[] aspects) - : this(aspects as IReadOnlyCollection>) { + this.aspects = aspects; } public CompositeEquality(IReadOnlyCollection> aspects) + : this(aspects.ToArray()) { - this.aspects = aspects; } public bool Equals(TSubject? x, TSubject? y) @@ -34,7 +37,15 @@ public bool Equals(TSubject? x, TSubject? y) return false; } - return aspects.All(aspect => aspect.Equals(x, y)); + foreach (var aspect in aspects) + { + if (!aspect.Equals(x, y)) + { + return false; + } + } + + return true; } public int GetHashCode(TSubject obj) @@ -44,12 +55,14 @@ public int GetHashCode(TSubject obj) return 0; } - return aspects.Aggregate( - 0, - (hashCode, aspect) => unchecked( - (hashCode * 397) ^ aspect.GetHashCode(obj) - ) - ); + var hash = new HashCode(); + foreach (var aspect in aspects) + { + var aspectHash = aspect.GetHashCode(obj); + hash.Add(aspectHash); + } + + return hash.ToHashCode(); } } } \ No newline at end of file diff --git a/src/Comparation/CompoundEquality.cs b/src/Comparation/CompoundEquality.cs new file mode 100644 index 0000000..882ab7c --- /dev/null +++ b/src/Comparation/CompoundEquality.cs @@ -0,0 +1,59 @@ +#if !NETSTANDARD2_0 +using System; +#endif +using System.Collections.Generic; + +namespace Comparation +{ + public sealed class CompoundEquality : IEqualityComparer + { + private readonly IEqualityComparer aspectA; + private readonly IEqualityComparer aspectB; + + public CompoundEquality( + IEqualityComparer aspectA, + IEqualityComparer aspectB) + { + this.aspectA = aspectA; + this.aspectB = aspectB; + } + + public bool Equals(TSubject? x, TSubject? y) + { + if (ReferenceEquals(x, y)) + { + return true; + } + + if (ReferenceEquals(x, null)) + { + return false; + } + + if (ReferenceEquals(y, null)) + { + return false; + } + + return aspectA.Equals(x, y) && aspectB.Equals(x, y); + } + + public int GetHashCode(TSubject obj) + { + if (obj is null) + { + return 0; + } + + var hash = new HashCode(); + + var aspectAHash = aspectA.GetHashCode(obj); + hash.Add(aspectAHash); + + var aspectBHash = aspectB.GetHashCode(obj); + hash.Add(aspectBHash); + + return hash.ToHashCode(); + } + } +} \ No newline at end of file diff --git a/src/Comparation/Equality.cs b/src/Comparation/Equality.cs index bf27f73..0e4f61b 100644 --- a/src/Comparation/Equality.cs +++ b/src/Comparation/Equality.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; namespace Comparation { @@ -64,11 +65,18 @@ public IEqualityComparer By( IEqualityComparer equality) => new ProjectingEquality(projection, equality); - public IEqualityComparer Composite(params IEqualityComparer[] aspects) => - Composite(aspects as IReadOnlyCollection>); + public IEqualityComparer Composite(params IEqualityComparer[] aspects) + { + if (aspects.Length == 2) + { + return new CompoundEquality(aspects[0], aspects[1]); + } + + return new CompositeEquality(aspects); + } public IEqualityComparer Composite(IReadOnlyCollection> aspects) => - new CompositeEquality(aspects); + Composite(aspects.ToArray()); public IEqualityComparer> Collection() => Collection(EqualityComparer.Default); @@ -81,5 +89,11 @@ public IEqualityComparer Composite(IReadOnlyCollection> Sequence(IEqualityComparer itemEquality) => new SequenceEquality(itemEquality); + + public IEqualityComparer> Set() => + Set(EqualityComparer.Default); + + public IEqualityComparer> Set(IEqualityComparer itemEquality) => + new SetEquality(itemEquality); } } \ No newline at end of file diff --git a/src/Comparation/EqualityExtensions.cs b/src/Comparation/EqualityExtensions.cs index baf4e24..e76d429 100644 --- a/src/Comparation/EqualityExtensions.cs +++ b/src/Comparation/EqualityExtensions.cs @@ -31,5 +31,9 @@ public static IEqualityComparer> ForCollection> ForSequence( this IEqualityComparer itemEquality) => Equality.Singleton.Sequence(itemEquality); + + public static IEqualityComparer> ForSet( + this IEqualityComparer itemEquality) => + Equality.Singleton.Set(itemEquality); } } \ No newline at end of file