Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions src/Comparation/CompositeEquality.cs
Original file line number Diff line number Diff line change
@@ -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<TSubject> : IEqualityComparer<TSubject>
{
private readonly IReadOnlyCollection<IEqualityComparer<TSubject>> aspects;
private readonly IEqualityComparer<TSubject>[] aspects;

public CompositeEquality(params IEqualityComparer<TSubject>[] aspects)
: this(aspects as IReadOnlyCollection<IEqualityComparer<TSubject>>)
{
this.aspects = aspects;
}

public CompositeEquality(IReadOnlyCollection<IEqualityComparer<TSubject>> aspects)
: this(aspects.ToArray())
{
this.aspects = aspects;
}

public bool Equals(TSubject? x, TSubject? y)
Expand All @@ -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)
Expand All @@ -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();
}
}
}
59 changes: 59 additions & 0 deletions src/Comparation/CompoundEquality.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#if !NETSTANDARD2_0
using System;
#endif
using System.Collections.Generic;

namespace Comparation
{
public sealed class CompoundEquality<TSubject> : IEqualityComparer<TSubject>
{
private readonly IEqualityComparer<TSubject> aspectA;
private readonly IEqualityComparer<TSubject> aspectB;

public CompoundEquality(
IEqualityComparer<TSubject> aspectA,
IEqualityComparer<TSubject> 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();
}
}
}
20 changes: 17 additions & 3 deletions src/Comparation/Equality.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Comparation
{
Expand Down Expand Up @@ -64,11 +65,18 @@ public IEqualityComparer<TSubject> By<TProjection>(
IEqualityComparer<TProjection> equality) =>
new ProjectingEquality<TSubject, TProjection>(projection, equality);

public IEqualityComparer<TSubject> Composite(params IEqualityComparer<TSubject>[] aspects) =>
Composite(aspects as IReadOnlyCollection<IEqualityComparer<TSubject>>);
public IEqualityComparer<TSubject> Composite(params IEqualityComparer<TSubject>[] aspects)
{
if (aspects.Length == 2)
{
return new CompoundEquality<TSubject>(aspects[0], aspects[1]);
}

return new CompositeEquality<TSubject>(aspects);
}

public IEqualityComparer<TSubject> Composite(IReadOnlyCollection<IEqualityComparer<TSubject>> aspects) =>
new CompositeEquality<TSubject>(aspects);
Composite(aspects.ToArray());

public IEqualityComparer<IReadOnlyCollection<TSubject?>> Collection() =>
Collection(EqualityComparer<TSubject>.Default);
Expand All @@ -81,5 +89,11 @@ public IEqualityComparer<TSubject> Composite(IReadOnlyCollection<IEqualityCompar

public IEqualityComparer<IReadOnlyCollection<TSubject?>> Sequence(IEqualityComparer<TSubject> itemEquality) =>
new SequenceEquality<TSubject>(itemEquality);

public IEqualityComparer<IReadOnlyCollection<TSubject?>> Set() =>
Set(EqualityComparer<TSubject>.Default);

public IEqualityComparer<IReadOnlyCollection<TSubject?>> Set(IEqualityComparer<TSubject> itemEquality) =>
new SetEquality<TSubject>(itemEquality);
}
}
4 changes: 4 additions & 0 deletions src/Comparation/EqualityExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,9 @@ public static IEqualityComparer<IReadOnlyCollection<TSubject>> ForCollection<TSu
public static IEqualityComparer<IReadOnlyCollection<TSubject>> ForSequence<TSubject>(
this IEqualityComparer<TSubject> itemEquality) =>
Equality<TSubject>.Singleton.Sequence(itemEquality);

public static IEqualityComparer<IReadOnlyCollection<TSubject>> ForSet<TSubject>(
this IEqualityComparer<TSubject> itemEquality) =>
Equality<TSubject>.Singleton.Set(itemEquality);
}
}