仅使用枚举的第一个字符转换为枚举
本文关键字:枚举 字符 转换 第一个 | 更新日期: 2023-09-27 17:56:33
我有以下枚举:
public enum GenderContract
{
Male,
Female,
Unknown
}
但我从客户那里得到了"M"、"F"和"U"的值。
是否有从枚举的第一个字符转换为实际枚举项的通用方法? (假设名称没有冲突?
我有几个这样的场景,我希望能够有一种通用的方法将部分匹配转换为枚举(而不仅仅是执行 switch 语句或类似的事情)。
简短的解决方案是使用"M"、"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';
与其依赖实际的枚举名称,不如考虑使用 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());
结果:
米
,一个简单的方法是使用这样的字典
var lookupTable = Enum.GetValues(typeof(GenderContract)).Cast<GenderContract>()
.ToDictionary(x => x.ToString()[0], x => x);
然后,它只是一个查找。
GenderContract e = lookupTable['M'];
我会以不同的方式做。由于您本质上需要一个查找表, 我会使用字典。
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)"
仅对于英语,您可以将枚举映射到 {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
名称的资源字符串,并通过"枚举类型+枚举值"查找字符串;
这是我想出的通用方法:
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
}
每次调用枚举时,这都会枚举枚举的名称,因此通过以某种方式存储枚举列表可能会提高性能,但我不需要那么多性能。
此外,如果有人更改我的枚举值,那么我的代码将失败,但我接受此解决方案的风险。