简体   繁体   English

严格将字符串解析为枚举的最佳方法是什么?

[英]What is the best way to strictly parse string to enum?

Let's say I have an enum: 假设我有一个枚举:

public enum MyEnum
{
    OptionOne = 0,
    OptionTwo = 2,
    OptionThree = 4
}

Like it was said in the How should I convert a string to an enum in C#? 就像我在C#中如何将字符串转换为枚举一样? question, I parse enum from string, using Enum.Parse method: 问题,我使用Enum.Parse方法从字符串解析枚举:

public class Enumer
{
    public static MyEnum? ParseEnum(string input)
    {
        try
        {
            return (MyEnum) Enum.Parse(typeof (MyEnum), input);
        }
        catch (ArgumentException)
        {
            return null;
        }
    }

}

Unfortunately, it doesn't work as expected with integer numbers, represented as strings. 不幸的是,它没有按预期使用整数,表示为字符串。
I do not expect Parse.Enum() to convert int from string, but actually it does. 我不希望Parse.Enum()从字符串转换int,但实际上它。
A simple test: 一个简单的测试:

[TestClass]
public class Tester
{
    [TestMethod]
    public void TestEnum()
    {
        Assert.AreEqual(MyEnum.OptionTwo, Enumer.ParseEnum("OptionTwo"));
        Assert.IsNull(Enumer.ParseEnum("WrongString"));
        Assert.IsNull(Enumer.ParseEnum("2")); // returns 2 instead of null
        Assert.IsNull(Enumer.ParseEnum("12345")); // returns 12345 instead of null
    }
}

Only two checks of four can be passed. 只能通过两次四次检查。
Enumer.ParseEnum("2") returns MyEnum.OptionTwo instead of null . Enumer.ParseEnum("2")返回MyEnum.OptionTwo而不是null
Moreover, Enumer.ParseEnum("12345") returns 12345, regardless it's out of the scope. 此外, Enumer.ParseEnum("12345")返回12345,无论它是否超出范围。

What is the best way to parse: 什么是解析的最佳方法:

  1. Only string values of "MyEnum.OptionOne", "MyEnum.OptionTwo", "MyEnum.OptionThree" into their enum counterparts. 只有字符串值“MyEnum.OptionOne”,“MyEnum.OptionTwo”,“MyEnum.OptionThree”进入其枚举对应物。
  2. Strings "MyEnum.OptionOne", "MyEnum.OptionTwo", "MyEnum.OptionThree" AND the values of 0, 2 and 4 into MyEnum.OptionOne, MyEnum.OptionTwo, MyEnum.OptionThree respectively? 字符串“MyEnum.OptionOne”,“MyEnum.OptionTwo”,“MyEnum.OptionThree”和0,2和4的值分别分别为MyEnum.OptionOne,MyEnum.OptionTwo,MyEnum.OptionThree?

The link to the similar question How should I convert a string to an enum in C#? 类似问题的链接我应该如何将字符串转换为C#中的枚举? doesn't help with the test provided - it still converts strings as integers, even when they are out of the enum scope. 对提供的测试没有帮助 - 它仍然将字符串转换为整数,即使它们不在枚举范围内。

You can do this yourself using Enum.GetValues(Type enumType) . 您可以使用Enum.GetValues(Type enumType)自己完成此操作。

public static MyEnum? ParseEnum(string input)
{
    return (MyEnum?) Enum.GetValues(typeof(MyEnum)).OfType<object>()
                         .FirstOrDefault(v => v.ToString() == input);
}

Adding support for integers you can also add. 添加对整数的支持,您也可以添加。

public static MyEnum? ParseEnum(string input)
{
    int value;
    var isInt = int.TryParse(input, out value);
    return (MyEnum?) Enum.GetValues(typeof(MyEnum)).OfType<object>()
                         .FirstOrDefault(v => v.ToString() == input
                                           || (isInt & (int)v == value));
}

Since I am not 100% sure about your last requirements I add one that includes the name as well and is more generic 由于我不是100%确定您的上一个要求,因此我添加一个包含该名称的内容并且更通用

public static T? ParseEnum<T>(string input)
    where T : struct 
{
    int value;
    var isInt = int.TryParse(input, out value);
    return (T?)Enum.GetValues(typeof(T)).OfType<object>()
                   .FirstOrDefault(v => v.ToString() == typeof(T).Name + input
                                    || (isInt & (int)v == value));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM