RSCG – Valuify
RSCG – Valuify
name | Valuify |
nuget | https://www.nuget.org/packages/Valuify/ |
link | https://github.com/MooVC/valuify |
author | Paul Martins |
Generating Equals from properties
This is how you can use Valuify .
The code that you start with is
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | < Project Sdk = "Microsoft.NET.Sdk" > < PropertyGroup > < OutputType >Exe</ OutputType > < TargetFramework >net9.0</ TargetFramework > < ImplicitUsings >enable</ ImplicitUsings > < Nullable >enable</ Nullable > </ PropertyGroup > < PropertyGroup > < EmitCompilerGeneratedFiles >true</ EmitCompilerGeneratedFiles > < CompilerGeneratedFilesOutputPath >$(BaseIntermediateOutputPath)\GX</ CompilerGeneratedFilesOutputPath > </ PropertyGroup > < ItemGroup > < PackageReference Include = "Valuify" Version = "1.1.0" > < PrivateAssets >all</ PrivateAssets > < IncludeAssets >runtime; build; native; contentfiles; analyzers; buildtransitive</ IncludeAssets > </ PackageReference > </ ItemGroup > </ Project > |
The code that you will use is
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | // See https://aka.ms/new-console-template for more information using GeneratorEqualsDemo; var p1 = new Person() { ID = 1, FirstName = "Andrei" , LastName = "Ignat" }; var p2= new Person() { ID = 1, FirstName = "Andrei" , LastName = "Ignat" }; Console.WriteLine(p1==p2); |
01 02 03 04 05 06 07 08 09 10 | namespace GeneratorEqualsDemo; [Valuify.Valuify] partial class Person { public int ID { get ; set ; } public string ? FirstName { get ; set ; } public string ? LastName { get ; set ; } } |
The code that is generated is
01 02 03 04 05 06 07 08 09 10 11 | namespace Valuify { using System; using System.Diagnostics.CodeAnalysis; [AttributeUsage(AttributeTargets.Class, Inherited = false , AllowMultiple = false )] internal sealed class ValuifyAttribute : Attribute { } } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | namespace GeneratorEqualsDemo { using System; using System.Collections.Generic; #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable disable #endif partial class Person { public static bool operator ==(Person left, Person right) { if (ReferenceEquals(left, right)) { return true ; } if (ReferenceEquals(left, null ) || ReferenceEquals(right, null )) { return false ; } return global::System.Collections.Generic.EqualityComparer< int >.Default.Equals(left.ID, right.ID) && global::System.Collections.Generic.EqualityComparer< string >.Default.Equals(left.FirstName, right.FirstName) && global::System.Collections.Generic.EqualityComparer< string >.Default.Equals(left.LastName, right.LastName); } } #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable restore #endif } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | namespace GeneratorEqualsDemo { using System; using System.Collections.Generic; #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable disable #endif partial class Person { public sealed override bool Equals( object other) { return Equals(other as Person); } } #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable restore #endif } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | namespace GeneratorEqualsDemo { using System; using System.Collections.Generic; #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable disable #endif partial class Person { public sealed override int GetHashCode() { return global::Valuify.Internal.HashCode.Combine(ID, FirstName, LastName); } } #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable restore #endif } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | namespace GeneratorEqualsDemo { using System; using System.Collections.Generic; #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable disable #endif partial class Person { public bool Equals(Person other) { return this == other; } } #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable restore #endif } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | namespace GeneratorEqualsDemo { using System; using System.Collections.Generic; #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable disable #endif partial class Person : IEquatable<Person> { } #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable restore #endif } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | namespace GeneratorEqualsDemo { using System; using System.Collections.Generic; #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable disable #endif partial class Person { public static bool operator !=(Person left, Person right) { return !(left == right); } } #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable restore #endif } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | namespace GeneratorEqualsDemo { using System; using System.Collections.Generic; #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable disable #endif partial class Person { public sealed override string ToString() { return string .Format( "Person { ID = {0}, FirstName = {1}, LastName = {2} }" , ID, FirstName, LastName); } } #if NET5_0_OR_GREATER || NETSTANDARD2_1_OR_GREATER #nullable restore #endif } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | namespace Valuify.Internal { using System; using System.Collections; internal static class HashCode { private const int HashSeed = 0x1505; private const int HashPrime = -1521134295; public static int Combine( params object [] values) { int hash = HashSeed; foreach ( object value in values) { if (value is IEnumerable && !(value is string )) { IEnumerable enumerable = (IEnumerable)value; foreach ( object element in enumerable) { hash = PerformCombine(hash, element); } } else { hash = PerformCombine(hash, value); } } return hash; } private static int PerformCombine( int hash, object value) { int other = GetHashCode(value); unchecked { return (other * HashPrime) + hash; } } private static int GetHashCode( object value) { int code = 0; if (value != null ) { code = value.GetHashCode(); } return code; } } } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | namespace Valuify.Internal { using System; using System.Collections; internal sealed class SequenceEqualityComparer { public static readonly SequenceEqualityComparer Default = new SequenceEqualityComparer(); public bool Equals(IEnumerable left, IEnumerable right) { if (ReferenceEquals(left, right)) { return true ; } if (ReferenceEquals(left, null ) || ReferenceEquals( null , right)) { return false ; } return Equals(left.GetEnumerator(), right.GetEnumerator()); } public int GetHashCode(IEnumerable enumerable) { return HashCode.Combine(enumerable); } private static bool Equals(IEnumerator left, IEnumerator right) { while (left.MoveNext()) { if (!right.MoveNext()) { return false ; } if (!Equals(left.Current, right.Current)) { return false ; } } return !right.MoveNext(); } } } |
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/Valuify