public void Should_use_member_hashing_function() { var foo = new Foo(); var configuration = new GetHashCodeConfiguration <Foo>().For(f => f.Number, (h, i) => 777); Func <Foo, int> customFn = new GetHashCodeExpressionBuilder <Foo>(configuration) .Build() .Compile(); int customNumberHash = customFn(foo); customNumberHash.Should().BeNotEqualToDefaultHashCodeOf(foo); }
public void Should_use_provided_primes() { var foo = new Foo(); var configuration = new GetHashCodeConfiguration <Foo>().WithPrimes(31, 41); Func <Foo, int> primesFn = new GetHashCodeExpressionBuilder <Foo>(configuration) .Build() .Compile(); int customPrimeHash = primesFn(foo); customPrimeHash.Should().BeNotEqualToDefaultHashCodeOf(foo); }
public void Should_not_take_member_into_account_if_it_is_registered_as_skipped() { var foo = new Foo(); var configuration = new GetHashCodeConfiguration <Foo>().Skip(f => f.Number); Func <Foo, int> skippedFn = new GetHashCodeExpressionBuilder <Foo>(configuration) .Build() .Compile(); int skippedNumberHash = skippedFn(foo); skippedNumberHash.Should().BeNotEqualToDefaultHashCodeOf(foo); }
public void Should_be_able_to_calculate_hash_code() { var foo = Dummy.Default; var configuration = new GetHashCodeConfiguration <Dummy>().WithPrimes(397, 0); var generator = new DynamicMethodGetHashCodeGenerator <Dummy>(configuration); Func <Dummy, int> hashFn = generator.Build(); int hashCode = hashFn(foo); int expectedHashCode = foo.GetHashCode(); hashCode.Should().Be(expectedHashCode); }
public void Should_not_hash_collection_items_if_registered() { var item = new Mock <Foo>(); var foo = new Foo() { Foos = new[] { item.Object, item.Object } }; var configuration = new GetHashCodeConfiguration <Foo>().ExcludeCollectionItems(); Func <Foo, int> hashFn = new GetHashCodeExpressionBuilder <Foo>(configuration) .Build() .Compile(); hashFn(foo); item.Verify(i => i.GetHashCode(), Times.Exactly(0)); }
public void Should_succeed_with_overflow() { checked { var foo = new Foo() { Number = int.MaxValue, Text = "some text" }; var configuration = new GetHashCodeConfiguration <Foo>().WithPrimes(int.MaxValue, int.MaxValue); Func <Foo, int> hashFn = new GetHashCodeExpressionBuilder <Foo>(configuration) .Build() .Compile(); Action action = () => hashFn(foo); action.ShouldNotThrow(); } }
public static void Register([NotNull] Action <GetHashCodeConfiguration <T> > configure) { try { var configuration = new GetHashCodeConfiguration <T>(); configure(configuration); Func <T, int> hashFn = new DynamicMethodGetHashCodeGenerator <T>(configuration).Build(); if (Interlocked.CompareExchange(ref hasher, hashFn, defaultHasher) != defaultHasher) { throw new InvalidOperationException($"Type '{typeof(T)}' was already registered with FastEasyHash"); } } catch (Exception ex) { initializationException = ex; } }
internal string BuildMsil(GetHashCodeConfiguration <T> configuration = null) => DynamicAssemblyMethodGenerator <Func <T, int> > .Build((ilGen) => new GetHashCodeIlGenerator <T>(configuration).Generate(ilGen)) .IlCode;
public GetHashCodeExpressionBuilder(GetHashCodeConfiguration <T> configuration = null) { _configuration = configuration ?? GetHashCodeConfiguration <T> .Default; }
public GetHashCodeIlGenerator(GetHashCodeConfiguration <T> configuration = null) { _configuration = configuration ?? GetHashCodeConfiguration <T> .Default; }
public DynamicMethodGetHashCodeGenerator(GetHashCodeConfiguration <T> configuration = null) { _configuration = configuration ?? GetHashCodeConfiguration <T> .Default; }