String representation of an Enum

后端 未结 30 2482
不思量自难忘°
不思量自难忘° 2020-11-22 02:44

I have the following enumeration:

public enum AuthenticationMethod
{
    FORMS = 1,
    WINDOWSAUTHENTICATION = 2,
    SINGLESIGNON = 3
}

T

30条回答
  •  情书的邮戳
    2020-11-22 03:06

    I created a base class for creating string-valued enums in .NET. It is just one C# file that you can copy & paste into your projects, or install via NuGet package named StringEnum. GitHub Repo

    • Intellisense will suggest the enum name if the class is annotated with the xml comment . (Works in both C# and VB)

    Intellisense demo

    • Usage similar to a regular enum:
    /// 
    class HexColor : StringEnum
    {
        public static readonly HexColor Blue = Create("#FF0000");
        public static readonly HexColor Green = Create("#00FF00");
        public static readonly HexColor Red = Create("#000FF");
    }
    
        // Static Parse Method
        HexColor.Parse("#FF0000") // => HexColor.Red
        HexColor.Parse("#ff0000", caseSensitive: false) // => HexColor.Red
        HexColor.Parse("invalid") // => throws InvalidOperationException
    
        // Static TryParse method.
        HexColor.TryParse("#FF0000") // => HexColor.Red
        HexColor.TryParse("#ff0000", caseSensitive: false) // => HexColor.Red
        HexColor.TryParse("invalid") // => null
    
        // Parse and TryParse returns the preexistent instances
        object.ReferenceEquals(HexColor.Parse("#FF0000"), HexColor.Red) // => true
    
        // Conversion from your `StringEnum` to `string`
        string myString1 = HexColor.Red.ToString(); // => "#FF0000"
        string myString2 = HexColor.Red; // => "#FF0000" (implicit cast)
    

    Instalation:

    • Paste the following StringEnum base class to your project. (latest version)
    • Or install StringEnum NuGet package, which is based on .Net Standard 1.0 so it runs on .Net Core >= 1.0, .Net Framework >= 4.5, Mono >= 4.6, etc.
        /// 
        /// Base class for creating string-valued enums in .NET.
    /// Provides static Parse() and TryParse() methods and implicit cast to string. ///
    /// /// /// class Color : StringEnum <Color> /// { /// public static readonly Color Blue = Create("Blue"); /// public static readonly Color Red = Create("Red"); /// public static readonly Color Green = Create("Green"); /// } /// /// /// The string-valued enum type. (i.e. class Color : StringEnum<Color>) public abstract class StringEnum : IEquatable where T : StringEnum, new() { protected string Value; private static Dictionary valueDict = new Dictionary(); protected static T Create(string value) { if (value == null) return null; // the null-valued instance is null. var result = new T() { Value = value }; valueDict.Add(value, result); return result; } public static implicit operator string(StringEnum enumValue) => enumValue.Value; public override string ToString() => Value; public static bool operator !=(StringEnum o1, StringEnum o2) => o1?.Value != o2?.Value; public static bool operator ==(StringEnum o1, StringEnum o2) => o1?.Value == o2?.Value; public override bool Equals(object other) => this.Value.Equals((other as T)?.Value ?? (other as string)); bool IEquatable.Equals(T other) => this.Value.Equals(other.Value); public override int GetHashCode() => Value.GetHashCode(); /// /// Parse the specified and returns a valid or else throws InvalidOperationException. /// /// The string value representad by an instance of . Matches by string value, not by the member name. /// If true, the strings must match case and takes O(log n). False allows different case but is little bit slower (O(n)) public static T Parse(string value, bool caseSensitive = true) { var result = TryParse(value, caseSensitive); if (result == null) throw new InvalidOperationException((value == null ? "null" : $"'{value}'") + $" is not a valid {typeof(T).Name}"); return result; } /// /// Parse the specified and returns a valid or else returns null. /// /// The string value representad by an instance of . Matches by string value, not by the member name. /// If true, the strings must match case. False allows different case but is slower: O(n) public static T TryParse(string value, bool caseSensitive = true) { if (value == null) return null; if (valueDict.Count == 0) System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle); // force static fields initialization if (caseSensitive) { if (valueDict.TryGetValue(value, out T item)) return item; else return null; } else { // slower O(n) case insensitive search return valueDict.FirstOrDefault(f => f.Key.Equals(value, StringComparison.OrdinalIgnoreCase)).Value; // Why Ordinal? => https://esmithy.net/2007/10/15/why-stringcomparisonordinal-is-usually-the-right-choice/ } } }

提交回复
热议问题