我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
我知道下面是不可能的,因为枚举的类型必须是int
enum GroupTypes
{
TheGroup = "OEM",
TheOtherGroup = "CMB"
}
从我的数据库中,我得到了一个不全面的代码字段(OEM和CMBs)。我想让这个字段成为一个枚举或其他可以理解的东西。因为如果目标是可读性,解决方案就应该简洁。
我还有其他选择吗?
当前回答
您是否考虑过使用字典查找表?
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()在读取字符串时查找它。
其他回答
在@Even Mien的回答之后,我试着走得更远一点,使它通用,我似乎几乎在那里,但有一种情况仍然抗拒,我可能可以简化我的代码一点。 我张贴在这里,如果有人看到我可以改进,特别是使它工作,因为我不能从字符串赋值
到目前为止,我有以下结果:
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"); } }
}
我甚至按照@Even(通过类X和公共静态X成员)的建议实现了一些枚举,只是为了后来发现,从。net 4.5开始,有了正确的ToString()方法。
现在我将所有内容重新实现为枚举。
基于https://stackoverflow.com/a/1343517/1818723,我提出了一个枚举与TryParse方法
public class FancyStringEnum
{
private FancyStringEnum(string value) { Value = value; }
public string Value { get; private set; }
private static List<FancyStringEnum> choices = new List<FancyStringEnum>
{
new FancyStringEnum("Small") ,
new FancyStringEnum("Big Thing") ,
new FancyStringEnum("Value with Spaces")
};
public static FancyStringEnum Small { get { return choices[0]; } }
public static FancyStringEnum BigThing { get { return choices[1]; } }
public static FancyStringEnum ValueWithSpaces { get { return choices[2]; } }
public override string ToString()
{
return Value;
}
public static bool TryParse(string value, bool ignoreCase, out FancyStringEnum result)
{
var sc = StringComparison.InvariantCulture;
if (ignoreCase)
sc = StringComparison.InvariantCultureIgnoreCase;
foreach (var choice in choices)
{
if (choice.Value.Equals(value, sc))
{
result = choice;
return true;
}
}
result = new FancyStringEnum(null);
return false;
}
public static FancyStringEnum Parse(string value, bool ignoreCase)
{
var sc = StringComparison.InvariantCulture;
if (ignoreCase)
sc = StringComparison.InvariantCultureIgnoreCase;
foreach (var choice in choices)
{
if (choice.Value.Equals(value, sc))
{
return choice;
}
}
return new FancyStringEnum(null);
}
}
传入类型安全的字符串值作为参数:
public static void Do(string message, FancyStringEnum value)
{
if (value == FancyStringEnum.Small)
{
//do something
} else if (value == FancyStringEnum.BigThing)
{
//do something else
}
}
TryParse和Parse在行动:
string something = "something"; //substiture with "small" to see it parsed
if (FancyStringEnum.TryParse(something, true, out var se))
Console.WriteLine(se.Value);
else
Console.WriteLine($"unable to parse {something}");
//or
var v2 = FancyStringEnum.Parse(something, true);
if (v2.Value == null)
Console.WriteLine($"unable to parse {something}");
else
Console.WriteLine(v2.Value); //do something with parsed enum
是否可以提取基类,用更少的代码创建StringEnums
您是否考虑过使用字典查找表?
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()在读取字符串时查找它。
c#不支持枚举字符串,但在大多数情况下,您可以使用List或Dictionary来获得所需的效果。
打印通过/失败结果:
List<string> PassFail = new List<string> { "FAIL", "PASS" };
bool result = true;
Console.WriteLine("Test1: " + PassFail[result.GetHashCode()]);