public static class SeparatorChars
{
public static String Comma { get { return ",";} }
public static String Tab { get { return "\t,";} }
public static String Space { get { return " ";} }
}
/// <summary>
/// Creates an List with all keys and values of a given Enum class
/// </summary>
/// <typeparam name="T">Must be derived from class Enum!</typeparam>
/// <returns>A list of KeyValuePair<Enum, string> with all available
/// names and values of the given Enum.</returns>
public static IList<KeyValuePair<T, string>> ToList<T>() where T : struct
{
var type = typeof(T);
if (!type.IsEnum)
{
throw new ArgumentException("T must be an enum");
}
return (IList<KeyValuePair<T, string>>)
Enum.GetValues(type)
.OfType<T>()
.Select(e =>
{
var asEnum = (Enum)Convert.ChangeType(e, typeof(Enum));
return new KeyValuePair<T, string>(e, asEnum.Description());
})
.ToArray();
}
现在您将有一个所有枚举的键值对及其描述的列表。因此,让我们简单地将它分配为一个组合框的数据源。
var comboBox = new ComboBox();
comboBox.ValueMember = "Key"
comboBox.DisplayMember = "Value";
comboBox.DataSource = EnumUtilities.ToList<Separator>();
comboBox.SelectedIndexChanged += (sender, e) =>
{
var selectedEnum = (Separator)comboBox.SelectedValue;
MessageBox.Show(selectedEnum.ToString());
}
public class GrainType
{
private string _typeKeyWord;
private GrainType(string typeKeyWord)
{
_typeKeyWord = typeKeyWord;
}
public override string ToString()
{
return _typeKeyWord;
}
public static GrainType Wheat = new GrainType("GT_WHEAT");
public static GrainType Corn = new GrainType("GT_CORN");
public static GrainType Rice = new GrainType("GT_RICE");
public static GrainType Barley = new GrainType("GT_BARLEY");
}
public abstract class StringEnumBase<T> : IEquatable<T>
where T : StringEnumBase<T>
{
public string Value { get; }
protected StringEnumBase(string value) => this.Value = value;
public override string ToString() => this.Value;
public static List<T> AsList()
{
return typeof(T)
.GetProperties(BindingFlags.Public | BindingFlags.Static)
.Where(p => p.PropertyType == typeof(T))
.Select(p => (T)p.GetValue(null))
.ToList();
}
public static T Parse(string value)
{
List<T> all = AsList();
if (!all.Any(a => a.Value == value))
throw new InvalidOperationException($"\"{value}\" is not a valid value for the type {typeof(T).Name}");
return all.Single(a => a.Value == value);
}
public bool Equals(T other)
{
if (other == null) return false;
return this.Value == other?.Value;
}
public override bool Equals(object obj)
{
if (obj == null) return false;
if (obj is T other) return this.Equals(other);
return false;
}
public override int GetHashCode() => this.Value.GetHashCode();
public static bool operator ==(StringEnumBase<T> a, StringEnumBase<T> b) => a?.Equals(b) ?? false;
public static bool operator !=(StringEnumBase<T> a, StringEnumBase<T> b) => !(a?.Equals(b) ?? false);
public class JsonConverter<T> : Newtonsoft.Json.JsonConverter
where T : StringEnumBase<T>
{
public override bool CanRead => true;
public override bool CanWrite => true;
public override bool CanConvert(Type objectType) => ImplementsGeneric(objectType, typeof(StringEnumBase<>));
private static bool ImplementsGeneric(Type type, Type generic)
{
while (type != null)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == generic)
return true;
type = type.BaseType;
}
return false;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken item = JToken.Load(reader);
string value = item.Value<string>();
return StringEnumBase<T>.Parse(value);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is StringEnumBase<T> v)
JToken.FromObject(v.Value).WriteTo(writer);
}
}
}
这就是你如何实现你的“字符串枚举”:
[JsonConverter(typeof(JsonConverter<Colour>))]
public class Colour : StringEnumBase<Colour>
{
private Colour(string value) : base(value) { }
public static Colour Red => new Colour("red");
public static Colour Green => new Colour("green");
public static Colour Blue => new Colour("blue");
}
可以这样使用:
public class Foo
{
public Colour colour { get; }
public Foo(Colour colour) => this.colour = colour;
public bool Bar()
{
if (this.colour == Colour.Red || this.colour == Colour.Blue)
return true;
else
return false;
}
}
下面的方法在你还没有完成你想要的 enum names,而 enum values是 enam name的 string表示的时候起作用; 使用 nameof()使你的重构更简单。
public static class Colours
{
public static string Red => nameof(Red);
public static string Green => nameof(Green);
public static string Blue => nameof(Blue);
}
public class ShapeTypes
{
private ShapeTypes() { }
public static string OVAL
{
get
{
return "ov";
}
private set { }
}
public static string SQUARE
{
get
{
return "sq";
}
private set { }
}
public static string RECTANGLE
{
get
{
return "rec";
}
private set { }
}
}
中创建字符串值枚举的基类。NET.它只是一个 C # 文件,您可以复制粘贴到您的项目,或通过名为 StringEnum的 NuGet 包安装。
用法:
///<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");
}
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;
}
}
public static class Extensions
{
public static string ToStringValue(this Enum en)
{
var type = en.GetType();
var memInfo = type.GetMember(en.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
var stringValue = ((DescriptionAttribute)attributes[0]).Description;
return stringValue;
}
}