我知道以下是不可能的,因为它必须是一个int
enum GroupTypes { TheGroup = "OEM", TheOtherGroup = "CMB" }
从我的数据库中我得到一个包含不全面代码的字段(OEM和CMB).我想把这个领域变成一个枚举或其他可以理解的东西.因为目标是可读性,所以解决方案应该简洁.
我还有其他选择吗?
我喜欢在类中使用属性而不是方法,因为它们看起来更像枚举.
以下是Logger的示例:
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);
您还可以使用扩展模型:
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());
如何使用带常量的静态类?客户端代码看起来与枚举没有什么不同.
static class GroupTypes { public const string TheGroup = "OEM"; public const string TheOtherGroup = "CMB"; } void DoSomething(string groupType) { if(groupType == GroupTypes.TheGroup) { // Be nice } else if (groupType == GroupTypes.TheOtherGroup) { // Continue to be nice } else { // unexpected, throw exception? } }
您可以向枚举中的项添加属性,然后使用反射从属性中获取值.
您必须使用"field"说明符来应用属性,如下所示:
enum GroupTypes { [field:Description("OEM")] TheGroup, [field:Description("CMB")] TheOtherGroup }
然后,您将反映枚举类型的静态字段(在本例中为GroupTypes),并DescriptionAttribute
使用反射获取您要查找的值:
public static DescriptionAttribute GetEnumDescriptionAttribute( 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 ().SingleOrDefault(); }
DescriptionAttribute
如果您希望能够确定属性是否应用,我选择返回上面的内容.
你可以很容易地做到这一点.使用以下代码.
enum GroupTypes { OEM, CMB };
然后,当您想要获取每个枚举元素的字符串值时,只需使用以下代码行.
String oemString = Enum.GetName(typeof(GroupTypes), GroupTypes.OEM);
我以前成功地使用过这个方法,并且我还使用了一个常量类来保存字符串常量,两者都运行得很好,但我更喜欢这个.
尝试将常量添加到静态类.你没有最终得到一个类型,但你有可读的,有组织的常量:
public static class GroupTypes { public const string TheGroup = "OEM"; public const string TheOtherGroup = "CMB"; }
为包含以下内容的数据库创建第二个枚举:
enum DBGroupTypes { OEM = 0, CMB = 1 }
现在,您可以使用Enum.Parse从字符串"OEM"和"CMB"中检索正确的DBGroupTypes值.然后,您可以将这些转换为int,并从您希望在模型中进一步使用的右枚举中检索正确的值.
使用课程.
编辑:更好的例子
class StarshipType { private string _Name; private static List_StarshipTypes = new List (); 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 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."); } }
这是我用来将枚举值作为字符串的扩展方法.首先是枚举.
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()); } }
处理问题的另一种方法是使用枚举和字符串数组,将枚举值与字符串列表进行映射:
public enum GroupTypes { TheGroup = 0, TheOtherGroup } string[] GroupTypesStr = { "OEM", "CMB" };
你可以使用这样的东西:
Log.Write(GroupTypesStr[(int)GroupTypes.TheOtherGroup]);
它会提示CMB
优点:
简单而干净的代码.
高性能(特别是与那些使用类的方法相比)
缺点:
在编辑时容易搞乱列表,但是对于一个简短的列表是可以的.