仅使用枚举的第一个char转换为枚举

时间:2016-07-12 22:21:50

标签: c# enums

我有以下枚举:

public enum GenderContract
{
    Male,
    Female,
    Unknown
}

但我从客户那里得到了' M' F' F'和' U'

是否有通用的方法从枚举的第一个字符转换为实际的枚举项? (假设名称中没有冲突?)

我有几个这样的场景,我希望能够有一种通用的方法将部分匹配转换为枚举(如果可能的话)(而不仅仅是做一个switch语句或类似的东西)。

6 个答案:

答案 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”查找字符串;