我有以下枚举:
public enum GenderContract
{
Male,
Female,
Unknown
}
但我从客户那里得到了' M' F' F'和' U'
是否有通用的方法从枚举的第一个字符转换为实际的枚举项? (假设名称中没有冲突?)
我有几个这样的场景,我希望能够有一种通用的方法将部分匹配转换为枚举(如果可能的话)(而不仅仅是做一个switch语句或类似的东西)。
答案 0 :(得分:5)
简短的解决方案是使用' M' F' F'和' U'
public enum GenderContract
{
Male = 77, // 'M'
Female = 70, // 'F'
Unknown = 80 // 'U'
};
然后你只需做
GenderContract c1 = (GenderContract)'M';
GenderContract c2 = (GenderContract)'F';
GenderContract c3 = (GenderContract)'U';
答案 1 :(得分:4)
您可能需要考虑使用DisplayAttribute,而不是依赖于实际的枚举名称。使用这意味着您的枚举值与字符串值没有很强的联系。 (也就是有人将女性改为女人并不会破坏这个价值)。
public enum GenderContract
{
[Display(ShortName="M")]
Male,
[Display(ShortName="F")]
Female,
[Display(ShortName="U")]
Unknown
}
然后是一个简单的扩展方法:
public static class EnumExtensions
{
public static TAttribute GetAttributeOrDefault<TAttribute>(this Enum enumVal)
where TAttribute : Attribute
{
var type = enumVal.GetType();
var memInfo = type.GetMember(enumVal.ToString());
var result = memInfo[0].GetCustomAttributes(typeof(TAttribute), false)
.FirstOrDefault() as TAttribute;
return result;
}
public static string ToName(this Enum value)
{
var result = value.ToString();
var attribute = value.GetAttributeOrDefault<DisplayAttribute>();
if (attribute != null)
{
result = attribute.Name;
}
return result;
}
public static string ToShortName(this Enum value)
{
var result = value.ToString();
var attribute = value.GetAttributeOrDefault<DisplayAttribute>();
if (attribute != null)
{
result = attribute.ShortName;
}
return result;
}
}
用法:
Console.WriteLine(GenderContract.Male.ToShortName());
结果:
中号
答案 2 :(得分:1)
我认为,一种简单的方法是使用像这样的字典
var lookupTable = Enum.GetValues(typeof(GenderContract)).Cast<GenderContract>()
.ToDictionary(x => x.ToString()[0], x => x);
然后,这只是一次查询。
GenderContract e = lookupTable['M'];
答案 3 :(得分:0)
我会以不同的方式做到这一点。因为你需要一个查找表, 我会用字典。
Dictionary<char, tuple<string, int>>
在哪里char
将是字典的关键; M,U,F 从我的评论。
然后元组看起来像Tuple<string, int> tuple = new Tuple<string, int> { {"Male", 0}, {"Unknown", 1}, {"Female", 2} }
。然后,您可以通过以下方式访问所需内容,myDictionaryTuple['U'].Item2
将返回Unknown = 1的整数值。
示例:
Dictionary<char, Tuple<string, int>> myDictionaryTuple = new Dictionary<char, Tuple<string, int>> { {'M', new Tuple<string, int>("Male", 0)}, {'F', new Tuple<string, int>("Female", 1) }, {'U', new Tuple<string, int>("Unknown", 2)}};
Console.WriteLine(myDictionaryTuple['U'].Item1); // Results in "Unknown"
Console.WriteLine(myDictionaryTuple['U'].Item2); // Results in 1
Console.WriteLine(myDictionaryTuple['U']); // Results in "(Unknown, 1)"
答案 4 :(得分:0)
这是我提出的通用方法:
void Main()
{
Console.WriteLine("M".SearchEnum<GenderContract>());
}
public static class EnumHelpers
{
public static T SearchEnum<T>(this string value)
{
if (value == null)
return default(T);
// Get the string names for the Enum
List<string> enumStrings = Enum.GetNames(typeof (T)).ToList();
string matchingEnumString = enumStrings.FirstOrDefault(x => x.StartsWith(value));
if (matchingEnumString == null)
throw new ArgumentException("Cannot convert " + value +
" to enum of " + typeof(T).FullName );
return ParseEnum<T>(matchingEnumString);
}
public static T ParseEnum<T>(this string value)
{
if (value == null)
return default(T);
return (T)Enum.Parse(typeof(T), value, true);
}
}
public enum GenderContract
{
Male,
Female,
Unknown
}
这会在每次调用时枚举枚举的名称,因此以某种方式存储枚举列表可能会更高效,但我不需要那么多的性能。
此外,如果有人更改了我的枚举值,那么我的代码将失败,但我接受此解决方案的风险。
答案 5 :(得分:0)
仅限英语,您可以将枚举映射到{enumValue,enumValue.ToString()}对的列表,并匹配字符串的前缀。
var allValues = Enum.GetValues(typeof(GenderContract))
.Cast<GenderContract>()
.Select(x => new {Value = x, Text = x.ToString()});
var result = allValues
.FirstOrDefault(x => x.Text.StartsWith("F", StringComparison.OrdinalIgnoreCase));
return result != null ? result.V : default(GenderContract);
如果您需要更多可本地化的解决方案,您可以在类似的代码中按名称将枚举值映射到资源字符串。即拥有GenderContract_Male
个名称的资源字符串,并按“enum type + enum value”查找字符串;