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
<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
// 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);
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
namespace Valuify { using System; using System.Diagnostics.CodeAnalysis; [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] internal sealed class ValuifyAttribute : Attribute { } }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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; } } }
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
Leave a Reply