ILLightenComparer 1.2.1
.NET 5.0
.NET Standard 2.0
dotnet add package ILLightenComparer --version 1.2.1
NuGet\Install-Package ILLightenComparer -Version 1.2.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ILLightenComparer" Version="1.2.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ILLightenComparer --version 1.2.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: ILLightenComparer, 1.2.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ILLightenComparer as a Cake Addin
#addin nuget:?package=ILLightenComparer&version=1.2.1
// Install ILLightenComparer as a Cake Tool
#tool nuget:?package=ILLightenComparer&version=1.2.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Fast comparer library
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
- Support for classes and structures any complexity and nesting.
- Highly configurable.
- Fluent intuitive API.
- Cycle detection.
- Collections comparison (
IEnumerable<T>
,T[]
,T[][]
). - .NET Standard 2.0, .NET 5.
- High performance.
- No 3<sup>rd</sup> party dependencies.
Configuration options
- Cycle detection.
- Ignoring collections order.
- Ignoring members.
- Including fields into comparison.
- Defining order in which members will be compared.
- Defining string comparison type.
- Defining custom comparers by type or instance.
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
- Configuration is fixed for generated comparer. If you want to change configuration you have to request new comparer:
var x = new Tuple<int, string>(1, "text"); var y = new Tuple<int, string>(2, "TEXT"); // initially configuration defines case insensitive string comparison var builder = new ComparerBuilder() .For<Tuple<int, string>>(c => c .SetStringComparisonType(StringComparison.CurrentCultureIgnoreCase) .DetectCycles(false)); // in addition, setup to ignore first member builder.Configure(c => c.IgnoreMember(o => o.Item1)); // this version takes in account only case insensitive second member var ignoreCaseComparer = builder.GetComparer(); // override string comparison type with case sensitive setting and build new comparer var originalCaseComparer = builder .For<Tuple<int, string>>() .Configure(c => c.SetStringComparisonType(StringComparison.Ordinal)) .GetComparer(); // first comparer ignores case for strings still ignoreCaseComparer.Compare(x, y).Should().Be(0); // second comparer still ignores first member but uses new string comparison type var result = originalCaseComparer.Compare(x, y); result.Should().Be(string.Compare("text", "TEXT", StringComparison.Ordinal));
- To help generate more effective code use
sealed
classes and small types (sbyte
,byte
,char
,short
,ushort
) when possible. - For safety reasons cycle detection is enabled by default. But when you are sure that it is not possible you can disable it and get significant performance boost.
- protected and private members are ignored during comparison.
- Multidimensional arrays are not supported now, but Jagged arrays are.
- If a type implements
IComparable<T>
interface then this implementations will be used. - Benchmarks
In case of an unexpected behavior, please welcome to create an issue and provide the type and data that you use.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- Illuminator (>= 0.4.0)
- System.Reflection.Emit (>= 4.7.0)
-
net5.0
- Illuminator (>= 0.4.0)
- System.Reflection.Emit (>= 4.7.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.