< Summary

Information
Class: MyNet.Primitives.SmartEnum<T1, T2>
Assembly: MyNet.Primitives
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/SmartEnum/SmartEnum.cs
Tag: 323_28699572109
Line coverage
100%
Covered lines: 44
Uncovered lines: 0
Coverable lines: 44
Total lines: 214
Line coverage: 100%
Branch coverage
70%
Covered branches: 17
Total branches: 24
Branch coverage: 70.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
get_Name()50%22100%
.ctor(...)100%22100%
get_All()100%11100%
Discover()66.66%66100%
TryFromValue(...)100%22100%
FromValue(...)75%44100%
Equals(...)50%22100%
GetHashCode()100%11100%
op_Equality(...)50%22100%
op_Inequality(...)100%11100%
CompareTo(...)50%22100%
System.IComparable.CompareTo(...)100%22100%
op_LessThan(...)100%11100%
op_LessThanOrEqual(...)100%11100%
op_GreaterThan(...)100%11100%
op_GreaterThanOrEqual(...)100%11100%
ToString()100%11100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/SmartEnum/SmartEnum.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="SmartEnum.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Collections.Concurrent;
 9using System.Collections.Generic;
 10using System.Diagnostics.CodeAnalysis;
 11using System.Linq;
 12using System.Reflection;
 13
 14#pragma warning disable IDE0130 // Namespace does not match folder structure
 15namespace MyNet.Primitives;
 16#pragma warning restore IDE0130 // Namespace does not match folder structure
 17
 18/// <summary>
 19/// Provides a strongly-typed enumeration pattern with support for any comparable, equatable value type.
 20/// </summary>
 21/// <remarks>
 22/// <para>
 23/// SmartEnum is a pattern for creating type-safe enumerations with custom logic and properties.
 24/// It automatically registers all static instances and provides efficient lookup by value.
 25/// </para>
 26/// <para>
 27/// Design principles:
 28/// - Single Responsibility: SmartEnum only handles enumeration logic
 29/// - Localization/humanization is handled by extension methods (Humanizer)
 30/// - This class keeps concerns separated and does not mix framework-specific features.
 31/// </para>
 32/// </remarks>
 33[SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = "SmartEnum is a well-k
 34public abstract class SmartEnum<TEnum, TValue> : IComparable, IComparable<SmartEnum<TEnum, TValue>>, ISmartEnum
 35    where TEnum : SmartEnum<TEnum, TValue>
 36    where TValue : IEquatable<TValue>, IComparable<TValue>
 37{
 2538    private static readonly Lazy<IReadOnlyCollection<TEnum>> LazyValues = new(Discover, isThreadSafe: true);
 2539    private static readonly ConcurrentDictionary<TValue, TEnum> ByValue = new();
 40
 41    /// <summary>
 42    /// Gets the underlying value.
 43    /// </summary>
 44    public TValue Value { get; }
 45
 46    /// <summary>
 47    /// Gets the display name (optional for UI layer, override if needed).
 48    /// </summary>
 2649    public virtual string Name => Value.ToString() ?? string.Empty;
 50
 51    /// <summary>
 52    /// Initializes a new instance of the <see cref="SmartEnum{TEnum,TValue}"/> class with the specified value.
 53    /// </summary>
 54    /// <param name="value">The value of the smart enum.</param>
 55    /// <exception cref="ArgumentNullException">Thrown when the value is null.</exception>
 56    /// <exception cref="InvalidOperationException">Thrown when a SmartEnum instance with the same value already exists.
 57    protected SmartEnum(TValue value)
 58    {
 251759        ArgumentNullException.ThrowIfNull(value);
 60
 251761        Value = value;
 62
 251763        if (!ByValue.TryAdd(value, (TEnum)this))
 64        {
 365            throw new InvalidOperationException(
 366                $"A {typeof(TEnum).Name} instance with value '{value}' already exists.");
 67        }
 251468    }
 69
 70    /// <summary>
 71    /// Gets all defined instances of this smart enum.
 72    /// </summary>
 3273    public static IReadOnlyCollection<TEnum> All => LazyValues.Value;
 74
 75    /// <summary>
 76    /// Returns all instances declared as static fields.
 77    /// </summary>
 78    private static TEnum[] Discover()
 79    {
 1680        var type = typeof(TEnum);
 81
 1682        var fields = type
 1683            .GetFields(BindingFlags.Public |
 1684                       BindingFlags.Static |
 1685                       BindingFlags.DeclaredOnly);
 86
 1687        var values = fields
 1688            .Where(f => f.FieldType == typeof(TEnum))
 1689            .Select(f => (TEnum)f.GetValue(null)!)
 1690            .ToArray();
 91
 355492        foreach (var v in values)
 176193            ByValue.TryAdd(v.Value, v);
 94
 1695        return values;
 96    }
 97
 98    /// <summary>
 99    /// Try to get an enum instance from value.
 100    /// </summary>
 101    public static bool TryFromValue(TValue value, out TEnum? result)
 102    {
 20103        if (ByValue.TryGetValue(value, out var match))
 104        {
 11105            result = match;
 11106            return true;
 107        }
 108
 9109        result = null;
 9110        return false;
 111    }
 112
 113    /// <summary>
 114    /// Get an enum instance from value.
 115    /// </summary>
 116    public static TEnum FromValue(TValue value) =>
 9117        TryFromValue(value, out var result) && result is not null
 9118            ? result
 9119            : throw new KeyNotFoundException(
 9120                $"No {typeof(TEnum).Name} found for value '{value}'.");
 121
 122    #region Equality
 123
 124    /// <summary>
 125    /// Determines whether the specified object is equal to the current instance. Two smart enum instances are considere
 126    /// </summary>
 127    /// <param name="obj">The object to compare with the current instance.</param>
 128    /// <returns>True if the specified object is equal to the current instance; otherwise, false.</returns>
 27129    public override bool Equals(object? obj) => obj is SmartEnum<TEnum, TValue> other && Value.Equals(other.Value);
 130
 131    /// <summary>
 132    /// Returns a hash code for the current instance. The hash code is based on the underlying value of the smart enum i
 133    /// </summary>
 134    /// <returns>A hash code for the current instance.</returns>
 6135    public override int GetHashCode() => Value.GetHashCode();
 136
 137    /// <summary>
 138    /// Determines whether two smart enum instances are equal. This operator overload allows you to compare two smart en
 139    /// </summary>
 140    /// <param name="left">The left smart enum instance to compare.</param>
 141    /// <param name="right">The right smart enum instance to compare.</param>
 142    /// <returns>True if the instances are equal; otherwise, false.</returns>
 6143    public static bool operator ==(SmartEnum<TEnum, TValue>? left, SmartEnum<TEnum, TValue>? right) => left?.Equals(righ
 144
 145    /// <summary>
 146    /// Determines whether two smart enum instances are not equal. This operator overload allows you to compare two smar
 147    /// </summary>
 148    /// <param name="left">The left smart enum instance to compare.</param>
 149    /// <param name="right">The right smart enum instance to compare.</param>
 150    /// <returns>True if the instances are not equal; otherwise, false.</returns>
 3151    public static bool operator !=(SmartEnum<TEnum, TValue>? left, SmartEnum<TEnum, TValue>? right) => !(left == right);
 152
 153    #endregion
 154
 155    #region Comparison
 156
 157    /// <summary>
 158    /// Compares the current instance with another smart enum instance of the same type and returns an integer that indi
 159    /// </summary>
 160    /// <param name="other">The other smart enum instance to compare.</param>
 161    /// <returns>A signed integer that indicates the relative order of the instances being compared.</returns>
 21162    public int CompareTo(SmartEnum<TEnum, TValue>? other) => other is null ? 1 : Value.CompareTo(other.Value);
 163
 164    /// <summary>
 165    /// Compares the current instance with another object and returns an integer that indicates the relative order.
 166    /// </summary>
 167    /// <param name="obj">The object to compare with the current instance.</param>
 168    /// <returns>A signed integer that indicates the relative order of the instances being compared.</returns>
 169    /// <exception cref="ArgumentException">Thrown when obj is not a SmartEnum instance or null.</exception>
 6170    int IComparable.CompareTo(object? obj) => obj is SmartEnum<TEnum, TValue> other
 6171        ? CompareTo(other)
 6172        : throw new ArgumentException($"Object must be of type {typeof(TEnum).Name}.", nameof(obj));
 173
 174    /// <summary>
 175    /// Determines whether one smart enum instance is less than another. This operator overload allows you to compare tw
 176    /// </summary>
 177    /// <param name="left">The left smart enum instance to compare.</param>
 178    /// <param name="right">The right smart enum instance to compare.</param>
 179    /// <returns>True if the left instance is less than the right instance; otherwise, false.</returns>
 3180    public static bool operator <(SmartEnum<TEnum, TValue> left, SmartEnum<TEnum, TValue> right) => left.CompareTo(right
 181
 182    /// <summary>
 183    /// Determines whether one smart enum instance is less than or equal to another. This operator overload allows you t
 184    /// </summary>
 185    /// <param name="left">The left smart enum instance to compare.</param>
 186    /// <param name="right">The right smart enum instance to compare.</param>
 187    /// <returns>True if the left instance is less than or equal to the right instance; otherwise, false.</returns>
 3188    public static bool operator <=(SmartEnum<TEnum, TValue> left, SmartEnum<TEnum, TValue> right) => left.CompareTo(righ
 189
 190    /// <summary>
 191    /// Determines whether one smart enum instance is greater than another. This operator overload allows you to compare
 192    /// </summary>
 193    /// <param name="left">The left smart enum instance to compare.</param>
 194    /// <param name="right">The right smart enum instance to compare.</param>
 195    /// <returns>True if the left instance is greater than the right instance; otherwise, false.</returns>
 3196    public static bool operator >(SmartEnum<TEnum, TValue> left, SmartEnum<TEnum, TValue> right) => left.CompareTo(right
 197
 198    /// <summary>
 199    /// Determines whether one smart enum instance is greater than or equal to another. This operator overload allows yo
 200    /// </summary>
 201    /// <param name="left">The left smart enum instance to compare.</param>
 202    /// <param name="right">The right smart enum instance to compare.</param>
 203    /// <returns>True if the left instance is greater than or equal to the right instance; otherwise, false.</returns>
 3204    public static bool operator >=(SmartEnum<TEnum, TValue> left, SmartEnum<TEnum, TValue> right) => left.CompareTo(righ
 205
 206    #endregion
 207
 208    /// <summary>
 209    /// Returns a string that represents the current instance. By default, this method returns the Name property of the 
 210    /// </summary>
 211    /// <returns>A string that represents the current instance.</returns>
 9212    public override string ToString() => Name;
 213}
 214