il-lighten-comparer

Fast comparer library

Build status codecov NuGet Badge

ILLightenComparer is a flexible library that can generate very effective and comprehensive IComparer<T> and IEqualityComparer<T> implementations on runtime using advantages of IL code emission.

Features

Configuration options

Examples

Basic usage

var comparer = ComparerBuilder.Default.GetComparer<Tuple<int, string>>();
var compareResult = comparer.Compare(x, y);

var equalityComparer = ComparerBuilder.Default.GetEqualityComparer<Tuple<int, string>>();
var equalityResult = equalityComparer.Equals(x, y);
var hashResult = equalityComparer.GetHashCode(x);

And it “just works”, no need complex configuration.

Ignore collection order

var x = new[] { 1, 2, 3 };
var y = new[] { 2, 3, 1 };

var comparer = new ComparerBuilder()
    .For<int[]>(c => c.IgnoreCollectionsOrder(true))
    .GetComparer();

var result = comparer.Compare(x, y);
result.Should().Be(0);

Ignore specific members

var x = new Tuple<int, string, double>(1, "value 1", 1.1);
var y = new Tuple<int, string, double>(1, "value 2", 2.2);

var comparer = new ComparerBuilder()
    .For<Tuple<int, string, double>>()
    .Configure(c => c.IgnoreMember(o => o.Item2)
                     .IgnoreMember(o => o.Item3))
    .GetComparer();

var result = comparer.Compare(x, y);
result.Should().Be(0);

Define custom comparer

var x = _fixture.Create<Tuple<int, string>>();
var y = _fixture.Create<Tuple<int, string>>();
var customComparer = new CustomizableComparer<Tuple<int, string>>((a, b) => 0); // makes all objects always equal

var comparer = new ComparerBuilder()
    .Configure(c => c.SetCustomComparer(customComparer))
    .GetComparer<Tuple<int, string>>();

var result = comparer.Compare(x, y);
result.Should().Be(0);

Define multiple configurations

var builder = new ComparerBuilder(c => c.SetDefaultCyclesDetection(false)); // defines initial configuration

// adds some configuration later
builder.Configure(c => c
    .SetStringComparisonType(
        typeof(Tuple<int, string, Tuple<short, string>>),
        StringComparison.InvariantCultureIgnoreCase)
    .IgnoreMember<Tuple<int, string, Tuple<short, string>>, int>(o => o.Item1));

// defines configuration for specific types
builder.For<Tuple<short, string>>(c => c.DefineMembersOrder(
    order => order.Member(o => o.Item2)
                  .Member(o => o.Item2)));

// adds additional configuration to existing configuration
builder.For<Tuple<int, string, Tuple<short, string>>>(c => c.IncludeFields(false));

Remarks

In case of an unexpected behavior, please welcome to create an issue and provide the type and data that you use.