我知道以下是不可能的,因为它必须是一个int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中我得到一个包含不全面代码的字段(OEM和CMB)。我想把这个字段变成一个枚举或其他可以理解的东西。因为目标是可读性,所以解决方案应该简洁 我还有其他选择吗?
答案 0 :(得分:288)
我喜欢在类中使用属性而不是方法,因为它们看起来更像枚举。
以下是记录器的示例:
public class LogCategory
{
private LogCategory(string value) { Value = value; }
public string Value { get; set; }
public static LogCategory Trace { get { return new LogCategory("Trace"); } }
public static LogCategory Debug { get { return new LogCategory("Debug"); } }
public static LogCategory Info { get { return new LogCategory("Info"); } }
public static LogCategory Warning { get { return new LogCategory("Warning"); } }
public static LogCategory Error { get { return new LogCategory("Error"); } }
}
将类型安全字符串值作为参数传递:
public static void Write(string message, LogCategory logCategory)
{
var log = new LogEntry { Message = message };
Logger.Write(log, logCategory.Value);
}
用法:
Logger.Write("This is almost like an enum.", LogCategory.Info);
答案 1 :(得分:131)
您还可以使用扩展模型:
public enum MyEnum
{
[Description("String 1")]
V1= 1,
[Description("String 2")]
V2= 2
}
您的分机课程
public static class MyEnumExtensions
{
public static string ToDescriptionString(this MyEnum val)
{
DescriptionAttribute[] attributes = (DescriptionAttribute[])val
.GetType()
.GetField(val.ToString())
.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : string.Empty;
}
}
用法:
MyEnum myLocal = MyEnum.V1;
print(myLocal.ToDescriptionString());
答案 2 :(得分:75)
如何使用带常量的静态类?客户端代码与枚举无异。
static class GroupTypes
{
public const string TheGroup = "OEM";
public const string TheOtherGroup = "CMB";
}
void DoSomething(GroupTypes groupType)
{
if(groupType == GroupTypes.TheOtherGroup)
{
//Launch nuclear bomb
}
}
答案 3 :(得分:28)
您可以为枚举中的项添加属性,然后使用反射从属性中获取值。
您必须使用“field”说明符来应用属性,如下所示:
enum GroupTypes
{
[field:Description("OEM")]
TheGroup,
[field:Description("CMB")]
TheOtherGroup
}
然后,您将反映枚举类型的静态字段(在本例中为GroupTypes),并使用反射获取您要查找的值的DescriptionAttribute
:
public static DescriptionAttribute GetEnumDescriptionAttribute<T>(
this T value) where T : struct
{
// The type of the enum, it will be reused.
Type type = typeof(T);
// If T is not an enum, get out.
if (!type.IsEnum)
throw new InvalidOperationException(
"The type parameter T must be an enum type.");
// If the value isn't defined throw an exception.
if (!Enum.IsDefined(type, value))
throw new InvalidEnumArgumentException(
"value", Convert.ToInt32(value), type);
// Get the static field for the value.
FieldInfo fi = type.GetField(value.ToString(),
BindingFlags.Static | BindingFlags.Public);
// Get the description attribute, if there is one.
return fi.GetCustomAttributes(typeof(DescriptionAttribute), true).
Cast<DescriptionAttribute>().SingleOrDefault();
}
如果您希望能够确定该属性是否已应用,我选择在上方返回DescriptionAttribute
。
答案 4 :(得分:19)
你可以很容易地做到这一点。使用以下代码。
enum GroupTypes
{
OEM,
CMB
};
然后,当你想获得每个枚举元素的字符串值时,只需使用以下代码行。
String oemString = Enum.GetName(typeof(GroupTypes), GroupTypes.OEM);
我以前成功地使用过这个方法,并且我还使用了一个常量类来保存字符串常量,两者都运行得很好,但我倾向于这个。
答案 5 :(得分:13)
为包含以下内容的数据库创建第二个枚举:
enum DBGroupTypes
{
OEM = 0,
CMB = 1
}
现在,您可以使用Enum.Parse从字符串“OEM”和“CMB”中检索正确的DBGroupTypes值。然后,您可以将这些转换为int,并从您希望在模型中进一步使用的右枚举中检索正确的值。
答案 6 :(得分:10)
使用课程。
编辑:更好的例子
class StarshipType
{
private string _Name;
private static List<StarshipType> _StarshipTypes = new List<StarshipType>();
public static readonly StarshipType Ultralight = new StarshipType("Ultralight");
public static readonly StarshipType Light = new StarshipType("Light");
public static readonly StarshipType Mediumweight = new StarshipType("Mediumweight");
public static readonly StarshipType Heavy = new StarshipType("Heavy");
public static readonly StarshipType Superheavy = new StarshipType("Superheavy");
public string Name
{
get { return _Name; }
private set { _Name = value; }
}
public static IList<StarshipType> StarshipTypes
{
get { return _StarshipTypes; }
}
private StarshipType(string name, int systemRatio)
{
Name = name;
_StarshipTypes.Add(this);
}
public static StarshipType Parse(string toParse)
{
foreach (StarshipType s in StarshipTypes)
{
if (toParse == s.Name)
return s;
}
throw new FormatException("Could not parse string.");
}
}
答案 7 :(得分:8)
尝试将常量添加到静态类。你没有最终得到一个类型,但你有可读的,有组织的常量:
public static class GroupTypes
{
public const string TheGroup = "OEM";
public const string TheOtherGroup = "CMB"
}
答案 8 :(得分:6)
这是我用来将枚举值作为字符串获取的扩展方法。首先是枚举。
public enum DatabaseEnvironment
{
[Description("AzamSharpBlogDevDatabase")]
Development = 1,
[Description("AzamSharpBlogQADatabase")]
QualityAssurance = 2,
[Description("AzamSharpBlogTestDatabase")]
Test = 3
}
Description属性来自System.ComponentModel。
这是我的扩展方法:
public static string GetValueAsString(this DatabaseEnvironment environment)
{
// get the field
var field = environment.GetType().GetField(environment.ToString());
var customAttributes = field.GetCustomAttributes(typeof (DescriptionAttribute), false);
if(customAttributes.Length > 0)
{
return (customAttributes[0] as DescriptionAttribute).Description;
}
else
{
return environment.ToString();
}
}
现在,您可以使用以下代码访问枚举作为字符串值:
[TestFixture]
public class when_getting_value_of_enum
{
[Test]
public void should_get_the_value_as_string()
{
Assert.AreEqual("AzamSharpBlogTestDatabase",DatabaseEnvironment.Test.GetValueAsString());
}
}
答案 9 :(得分:6)
处理问题的另一种方法是使用枚举和字符串数组,将枚举值与字符串列表进行映射:
public enum GroupTypes
{
TheGroup = 0,
TheOtherGroup
}
string[] GroupTypesStr = {
"OEM",
"CMB"
};
你可以使用这样的东西:
Log.Write(GroupTypesStr[(int)GroupTypes.TheOtherGroup]);
它会提示CMB
优点:
CONS:
答案 10 :(得分:3)
您是否考虑使用词典查找表?
enum GroupTypes
{
TheGroup,
TheOtherGroup
}
Dictionary<string, GroupTypes> GroupTypeLookup = new Dictionary<string, GroupTypes>();
// initialize lookup table:
GroupTypeLookup.Add("OEM", TheGroup);
GroupTypeLookup.Add("CMB", TheOtherGroup);
然后,您可以在阅读时使用GroupTypeLookup.TryGetValue()查找字符串。
答案 11 :(得分:3)
C#不支持枚举字符串,但在大多数情况下,您可以使用List或Dictionary来获得所需的效果。
E.g。要打印通过/未通过结果:
List<string> PassFail = new List<string> { "FAIL", "PASS" };
bool result = true;
Console.WriteLine("Test1: " + PassFail[result.GetHashCode()]);
答案 12 :(得分:2)
为什么不使用相同的枚举,而只是调用 .ToString()
?
using System;
public class EnumSample
{
enum Holidays
{
Christmas = 1,
Easter = 2
};
public static void Main()
{
Enum myHolidays = Holidays.Christmas;
Console.WriteLine("The value of this instance is '{0}'", myHolidays.ToString());
}
}
答案 13 :(得分:2)
我只想创建一个字典并使用代码作为密钥。
编辑:要解决有关进行反向查找(找到密钥)的注释,这将不会非常有效。如果有必要,我会编写一个新类来处理它。
答案 14 :(得分:2)
public class DataType
{
private readonly string value;
private static readonly Dictionary<string, DataType> predefinedValues;
public static readonly DataType Json = new DataType("json");
public static readonly DataType Xml = new DataType("xml");
public static readonly DataType Text = new DataType("text");
public static readonly DataType Html = new DataType("html");
public static readonly DataType Binary = new DataType("binary");
static DataType()
{
predefinedValues = new Dictionary<string, DataType>();
predefinedValues.Add(Json.Value, Json);
predefinedValues.Add(Xml.Value, Xml);
predefinedValues.Add(Text.Value, Text);
predefinedValues.Add(Html.Value, Html);
predefinedValues.Add(Binary.Value, Binary);
}
private DataType(string value)
{
this.value = value;
}
public static DataType Parse(string value)
{
var exception = new FormatException($"Invalid value for type {nameof(DataType)}");
if (string.IsNullOrEmpty(value))
throw exception;
string key = value.ToLower();
if (!predefinedValues.ContainsKey(key))
throw exception;
return predefinedValues[key];
}
public string Value
{
get { return value; }
}
}
答案 15 :(得分:2)
对Glennular Extension方法的一个小调整,所以你可以在其他东西上使用扩展而不仅仅是ENUM;
using System;
using System.ComponentModel;
namespace Extensions {
public static class T_Extensions {
/// <summary>
/// Gets the Description Attribute Value
/// </summary>
/// <typeparam name="T">Entity Type</typeparam>
/// <param name="val">Variable</param>
/// <returns>The value of the Description Attribute or an Empty String</returns>
public static string Description<T>(this T t) {
DescriptionAttribute[] attributes = (DescriptionAttribute[])t.GetType().GetField(t.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : string.Empty;
}
}
}
或使用Linq
using System;
using System.ComponentModel;
using System.Linq;
namespace Extensions {
public static class T_Extensions {
public static string Description<T>(this T t) =>
((DescriptionAttribute[])t
?.GetType()
?.GetField(t?.ToString())
?.GetCustomAttributes(typeof(DescriptionAttribute), false))
?.Select(a => a?.Description)
?.FirstOrDefault()
?? string.Empty;
}
}
答案 16 :(得分:2)
我的第一个问题 - 您是否可以访问数据库本身?这应该在数据库中标准化,理想情况下,否则,任何解决方案都将容易出错。根据我的经验,充满“OEM”和“CMB”的数据字段往往随着时间的推移而混合“oem”和其他“废话数据”之类的东西....如果你可以将其标准化,你可以使用密钥在包含元素作为你的枚举的表中,你已经完成了,结构更清晰。
如果没有,我会制作你的Enum,然后上课,将你的字符串解析为Enum。与使用Enum.Parse / Reflection / etc执行任何变通方法相比,这至少可以为您提供处理非标准条目的灵活性以及陷阱或处理错误的更大灵活性。字典可以工作,但如果您遇到案例问题,可能会崩溃等等。
我建议写一堂课,这样你就可以:
// I renamed this to GroupType, since it sounds like each element has a single type...
GroupType theType = GroupTypeParser.GetGroupType(theDBString);
这样可以保留大部分可读性,而无需更改数据库。
答案 17 :(得分:2)
我会把它变成一个完全避免枚举的类。然后使用类型处理程序,您可以在从数据库中获取对象时创建该对象。
IE:
public class Group
{
public string Value{ get; set; }
public Group( string value ){ Value = value; }
public static Group TheGroup() { return new Group("OEM"); }
public static Group OtherGroup() { return new Group("CMB"); }
}
答案 18 :(得分:2)
如果我理解正确,您需要从字符串转换为枚举:
enum GroupTypes {
Unknown = 0,
OEM = 1,
CMB = 2
}
static GroupTypes StrToEnum(string str){
GroupTypes g = GroupTypes.Unknown;
try {
object o = Enum.Parse(typeof(GroupTypes), str, true);
g = (GroupTypes)(o ?? 0);
} catch {
}
return g;
}
// then use it like this
GroupTypes g1 = StrToEnum("OEM");
GroupTypes g2 = StrToEnum("bad value");
如果您愿意,可以使用enum类型的泛型更加花哨。
答案 19 :(得分:1)
在VS 2015中,您可以使用nameof
public class LogCategory
{
public static string Trace;
public static string Debug;
public static string Info;
public static string Warning;
public static string Error;
}
用法:
Logger.Write("This is almost like an enum.", nameof(LogCategory.Info));
答案 20 :(得分:1)
这是一种将用作强类型参数或字符串的方法:
public class ClassLikeEnum
{
public string Value
{
get;
private set;
}
ClassLikeEnum(string value)
{
Value = value;
}
public static implicit operator string(ClassLikeEnum c)
{
return c.Value;
}
public static readonly ClassLikeEnum C1 = new ClassLikeEnum("RandomString1");
public static readonly ClassLikeEnum C2 = new ClassLikeEnum("RandomString2");
}
答案 21 :(得分:1)
您可以使用两个枚举。一个用于数据库,另一个用于可读性。
你只需要确保它们保持同步,这似乎是一个小成本。 您不必设置值,只需设置相同的位置,但设置值可以非常清楚两个枚举相关并防止错误重新排列枚举成员。评论让维护人员知道这些是相关的,必须保持同步。
// keep in sync with GroupTypes
public enum GroupTypeCodes
{
OEM,
CMB
}
// keep in sync with GroupTypesCodes
public enum GroupTypes
{
TheGroup = GroupTypeCodes.OEM,
TheOtherGroup = GroupTypeCodes.CMB
}
要使用它,您只需先转换为代码:
GroupTypes myGroupType = GroupTypes.TheGroup;
string valueToSaveIntoDatabase = ((GroupTypeCodes)myGroupType).ToString();
然后,如果您想使它更方便,您可以添加仅适用于此类枚举的扩展功能:
public static string ToString(this GroupTypes source)
{
return ((GroupTypeCodes)source).ToString();
}
然后你可以这样做:
GroupTypes myGroupType = GroupTypes.TheGroup;
string valueToSaveIntoDatabase = myGroupType.ToString();
答案 22 :(得分:1)
我基本上是在寻找@ArthurC的反思答案
只是稍微扩展他的答案,你可以通过一个通用函数使它更好:
// If you want for a specific Enum
private static string EnumStringValue(GroupTypes e)
{
return EnumStringValue<GroupTypes>(e);
}
// Generic
private static string EnumStringValue<T>(T enumInstance)
{
return Enum.GetName(typeof(T), enumInstance);
}
然后你可以包装你拥有的任何东西
EnumStringValue(GroupTypes.TheGroup) // if you incorporate the top part
或
EnumStringValue<GroupTypes>(GroupTypes.TheGroup) // if you just use the generic
答案 23 :(得分:1)
我甚至按照@Even(通过class X
和public static X
成员的建议)实施了一些枚举,以便稍后了解这些天,从.Net 4.5开始,右边 ToString()
方法。
现在我重新将所有内容重新添加到枚举中。
答案 24 :(得分:1)
添加此类
public class DatabasePreference {
public DatabasePreference([CallerMemberName] string preferenceName = "") {
PreferenceName = preferenceName;
}
public string PreferenceName;
}
这项工作正在使用CallerMemberName
来最大限度地减少编码
使用:
//Declare names
public static DatabasePreference ScannerDefaultFlashLight = new DatabasePreference();
public static DatabasePreference ScannerQrCodes = new DatabasePreference();
public static DatabasePreference Scanner1dCodes = new DatabasePreference();
测试:
Console.WriteLine(ScannerDefaultFlashLight.PreferenceName);
Console.WriteLine(ScannerDefaultFlashLight.Scanner1dCodes);
输出:
ScannerDefaultFlashLight
Scanner1dCodes
答案 25 :(得分:0)
根据其他意见,这是我想出的。这种方法避免了在你想要获得常量值的地方输入.Value。
我有这样的所有字符串枚举的基类:
using System;
using Newtonsoft.Json;
[JsonConverter(typeof(ConstantConverter))]
public class StringEnum: IConvertible
{
public string Value { get; set; }
protected StringEnum(string value)
{
Value = value;
}
public static implicit operator string(StringEnum c)
{
return c.Value;
}
public string ToString(IFormatProvider provider)
{
return Value;
}
public TypeCode GetTypeCode()
{
throw new NotImplementedException();
}
public bool ToBoolean(IFormatProvider provider)
{
throw new NotImplementedException();
}
//The same for all the rest of IConvertible methods
}
JsonConverter是这样的:
using System;
using Newtonsoft.Json;
class ConstantConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
serializer.Serialize(writer, null);
}
else
{
serializer.Serialize(writer, value.ToString());
}
}
}
实际的字符串枚举将是这样的:
public sealed class Colors : StringEnum
{
public static Colors Red { get { return new Catalog("Red"); } }
public static Colors Yellow { get { return new Catalog("Yellow"); } }
public static Colors White { get { return new Catalog("White"); } }
private Colors(string value) : base(value) { }
}
有了这个,您可以使用Color.Red甚至序列化为json而不使用Value属性
答案 26 :(得分:0)
我已经做了类似的事情;
public enum BusinessUnits
{
NEW_EQUIPMENT = 0,
USED_EQUIPMENT = 1,
RENTAL_EQUIPMENT = 2,
PARTS = 3,
SERVICE = 4,
OPERATOR_TRAINING = 5
}
public class BusinessUnitService
{
public static string StringBusinessUnits(BusinessUnits BU)
{
switch (BU)
{
case BusinessUnits.NEW_EQUIPMENT: return "NEW EQUIPMENT";
case BusinessUnits.USED_EQUIPMENT: return "USED EQUIPMENT";
case BusinessUnits.RENTAL_EQUIPMENT: return "RENTAL EQUIPMENT";
case BusinessUnits.PARTS: return "PARTS";
case BusinessUnits.SERVICE: return "SERVICE";
case BusinessUnits.OPERATOR_TRAINING: return "OPERATOR TRAINING";
default: return String.Empty;
}
}
}
以此命名;
BusinessUnitService.StringBusinessUnits(BusinessUnits.PARTS)
答案 27 :(得分:0)
我想避免完全使用字符串文字,而且我不需要在项目描述中留出空格。更重要的是,我想拥有一种机制来检查提供的字符串是否有效,因此我想出了以下解决方案:
public class Seasons
{
public static string Spring { get; }
public static string Summer { get; }
public static string Fall { get; }
public static string Winter { get; }
public static bool IsValid(string propertyName)
{
if (string.IsNullOrEmpty(propertyName))
{
return false;
}
try
{
return typeof(Seasons).GetProperty(propertyName) != null;
}
catch
{
return false;
}
}
}
这是它的工作方式:
void Main()
{
string s = nameof(Seasons.Fall);
Console.WriteLine($"Fall is valid: {Seasons.IsValid(s)}"); // true
s = "WrongSeason";
Console.WriteLine($"WrongSeason is valid: {Seasons.IsValid(s)}"); // false
}
我试图将IsValid()重构为基类,并使用反射来读取类型(MethodBase.GetCurrentMethod()。DeclaringType),但是由于我想使其为静态,因此它返回基类类型,而不是继承的类型类型。您对此的补救措施将非常受欢迎!这是我想要实现的目标:
public class Seasons : ConstantStringsBase
{
// ... same
}
public class ConstantStringsBase
{
public static bool IsValid(string propertyName)
{
return MethodBase.GetCurrentMethod().DeclaringType.GetProperty(propertyName) != null;
}
}
答案 28 :(得分:0)
在@Even Mien的回答之后,我尝试进一步介绍一下并使其通用(Generic),我似乎差不多了,但是有一种情况仍然可以抗拒,我可能可以简化一下代码。
我将其发布在这里,如果有人看到我可以改进的地方,尤其是使其无法工作,因为我无法通过字符串分配它
到目前为止,我得到以下结果:
Console.WriteLine(TestEnum.Test1);//displays "TEST1"
bool test = "TEST1" == TestEnum.Test1; //true
var test2 = TestEnum.Test1; //is TestEnum and has value
string test3 = TestEnum.Test1; //test3 = "TEST1"
var test4 = TestEnum.Test1 == TestEnum.Test2; //false
EnumType<TestEnum> test5 = "TEST1"; //works fine
//TestEnum test5 = "string"; DOESN'T compile .... :(:(
神奇发生的地方:
public abstract class EnumType<T> where T : EnumType<T>
{
public string Value { get; set; }
protected EnumType(string value)
{
Value = value;
}
public static implicit operator EnumType<T>(string s)
{
if (All.Any(dt => dt.Value == s))
{
Type t = typeof(T);
ConstructorInfo ci = t.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic,null, new Type[] { typeof(string) }, null);
return (T)ci.Invoke(new object[] {s});
}
else
{
return null;
}
}
public static implicit operator string(EnumType<T> dt)
{
return dt?.Value;
}
public static bool operator ==(EnumType<T> ct1, EnumType<T> ct2)
{
return (string)ct1 == (string)ct2;
}
public static bool operator !=(EnumType<T> ct1, EnumType<T> ct2)
{
return !(ct1 == ct2);
}
public override bool Equals(object obj)
{
try
{
return (string)obj == Value;
}
catch
{
return false;
}
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public static IEnumerable<T> All
=> typeof(T).GetProperties()
.Where(p => p.PropertyType == typeof(T))
.Select(x => (T)x.GetValue(null, null));
}
然后我只需要为我的枚举声明它:
public class TestEnum : EnumType<TestEnum>
{
private TestEnum(string value) : base(value)
{}
public static TestEnum Test1 { get { return new TestEnum("TEST1"); } }
public static TestEnum Test2 { get { return new TestEnum("TEST2"); } }
}
答案 29 :(得分:0)
来自@EvenMien,并添加了一些评论。 (也是我自己的用例)
public struct AgentAction
{
private AgentAction(string value) { Value = value; }
public string Value { get; private set; }
public override string ToString()
{
return this.Value;
}
public static AgentAction Login = new AgentAction("Logout");
public static AgentAction Logout = new AgentAction("Logout");
public static implicit operator string(AgentAction action) { return action.ToString(); }
}
答案 30 :(得分:0)
.Net Core 3.0 / C#8.0 中的新增功能(如果您的工作环境允许您升级项目)是一种简短的切换语句,看起来有些枚举。归根结底,这是我们多年以来一直在使用的旧无聊的switch语句。
唯一真正的区别是switch语句有了新的用法。
public static RGBColor FromRainbow(Rainbow colorBand) =>
colorBand switch
{
Rainbow.Red => new RGBColor(0xFF, 0x00, 0x00),
Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
Rainbow.Green => new RGBColor(0x00, 0xFF, 0x00),
Rainbow.Blue => new RGBColor(0x00, 0x00, 0xFF),
Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
_ => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),
};
您会注意到,我从here复制的代码实际上是使用枚举作为参数。
这不完全是您想要的(相信我,我一直希望获得与OP所要求的类似的东西),但实际上我感觉这有点像MS的橄榄枝。 JMO。
希望它对某人有帮助!
答案 31 :(得分:0)
我使用了上一个答案中提到的结构,但是消除了任何复杂性。对我而言,这最像是创建字符串枚举。它的使用方式与枚举相同。
struct ViewTypes
{
public const string View1 = "Whatever string you like";
public const string View2 = "another string";
}
示例用法:
switch( some_string_variable )
{
case ViewTypes.View1: /* do something */ break;
case ViewTypes.View2: /* do something else */ break;
}
答案 32 :(得分:0)
我不需要像在属性中存储字符串那样健壮。我只需要将MyEnum.BillEveryWeek
之类的内容转换为“每周一次的账单”或MyEnum.UseLegacySystem
转换为“使用遗留系统” - 基本上将enum的骆驼套管分成单个小写单词。
public static string UnCamelCase(this Enum input, string delimiter = " ", bool preserveCasing = false)
{
var characters = input.ToString().Select((x, i) =>
{
if (i > 0 && char.IsUpper(x))
{
return delimiter + x.ToString(CultureInfo.InvariantCulture);
}
return x.ToString(CultureInfo.InvariantCulture);
});
var result = preserveCasing
? string.Concat(characters)
: string.Concat(characters).ToLower();
var lastComma = result.LastIndexOf(", ", StringComparison.Ordinal);
if (lastComma > -1)
{
result = result.Remove(lastComma, 2).Insert(lastComma, " and ");
}
return result;
}
MyEnum.UseLegacySystem.UnCamelCase()
输出“使用遗留系统”
如果您设置了多个标志,它会将其转换为普通英语(逗号分隔,除了“和”代替最后一个逗号)。
var myCustomerBehaviour = MyEnum.BillEveryWeek | MyEnum.UseLegacySystem | MyEnum.ChargeTaxes;
Console.WriteLine(myCustomerBehaviour.UnCamelCase());
//outputs "bill every week, use legacy system and charge taxes"