Я створив базовий клас для створення рядкових перерахувань у .NET. Це лише один файл C #, який ви можете скопіювати та вставити у свої проекти або встановити за допомогою пакета NuGet з іменем StringEnum .
Використання:
///<completionlist cref="HexColor"/>
class HexColor : StringEnum<HexColor>
{
public static readonly HexColor Blue = New("#FF0000");
public static readonly HexColor Green = New("#00FF00");
public static readonly HexColor Red = New("#000FF");
}
Особливості
- Ваш StringEnum виглядає дещо схожим на звичайний перелік:
// 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)
- Intellisense запропонує ім'я переліку, якщо клас анотовано коментарем xml
<completitionlist>
. (Працює як на C #, так і на VB): тобто
Встановлення
Або:
- Встановіть найновіший пакет StringEnum NuGet, який базується на
.Net Standard 1.0
тому, що він працює на .Net Core
> = 1.0, .Net Framework
> = 4.5, Mono
> = 4.6 тощо.
- Або вставте наступний базовий клас StringEnum у свій проект. ( остання версія )
public abstract class StringEnum<T> : IEquatable<T> where T : StringEnum<T>, new()
{
protected string Value;
private static IList<T> valueList = new List<T>();
protected static T New(string value)
{
if (value == null)
return null; // the null-valued instance is null.
var result = new T() { Value = value };
valueList.Add(result);
return result;
}
public static implicit operator string(StringEnum<T> enumValue) => enumValue.Value;
public override string ToString() => Value;
public static bool operator !=(StringEnum<T> o1, StringEnum<T> o2) => o1?.Value != o2?.Value;
public static bool operator ==(StringEnum<T> o1, StringEnum<T> o2) => o1?.Value == o2?.Value;
public override bool Equals(object other) => this.Value.Equals((other as T)?.Value ?? (other as string));
bool IEquatable<T>.Equals(T other) => this.Value.Equals(other.Value);
public override int GetHashCode() => Value.GetHashCode();
/// <summary>
/// Parse the <paramref name="value"/> specified and returns a valid <typeparamref name="T"/> or else throws InvalidOperationException.
/// </summary>
/// <param name="value">The string value representad by an instance of <typeparamref name="T"/>. Matches by string value, not by the member name.</param>
/// <param name="caseSensitive">If true, the strings must match case sensitivity.</param>
public static T Parse(string value, bool caseSensitive = false)
{
var result = TryParse(value, caseSensitive);
if (result == null)
throw new InvalidOperationException((value == null ? "null" : $"'{value}'") + $" is not a valid {typeof(T).Name}");
return result;
}
/// <summary>
/// Parse the <paramref name="value"/> specified and returns a valid <typeparamref name="T"/> or else returns null.
/// </summary>
/// <param name="value">The string value representad by an instance of <typeparamref name="T"/>. Matches by string value, not by the member name.</param>
/// <param name="caseSensitive">If true, the strings must match case sensitivity.</param>
public static T TryParse(string value, bool caseSensitive = false)
{
if (value == null) return null;
if (valueList.Count == 0) System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle); // force static fields initialization
var field = valueList.FirstOrDefault(f => f.Value.Equals(value,
caseSensitive ? StringComparison.Ordinal
: StringComparison.OrdinalIgnoreCase));
// Not using InvariantCulture because it's only supported in NETStandard >= 2.0
if (field == null)
return null;
return field;
}
}
- Для
Newtonsoft.Json
підтримки серіалізації скопіюйте цю розширену версію. StringEnum.cs
Я зрозумів, що цей код схожий на відповідь Бена. Я щиро писав це з нуля. Однак я думаю, що у нього є кілька додаткових функцій, наприклад, <completitionlist>
хак, отриманий клас більше схожий на Enum, не використовуючи роздумів про Parse (), пакет NuGet та репо, де я, сподіваюся, розгляну вхідні проблеми та відгуки.