如何在忽略大小写的情况下测试是否定义了枚举?

Edw*_*uay 32 c# enums case-sensitive

以下通用静态方法接受一个字符串并返回一个枚举.

因为我将ignoreCase参数设置为true,所以很好地忽略了大小写.

但是,我还想测试枚举是否存在,但执行此操作的enum.IsDefined方法似乎没有ignoreCase参数.

如何测试枚举是否被定义,并且在同一个忽略的情况下?

using System;

namespace TestEnum2934234
{
    class Program
    {
        static void Main(string[] args)
        {
            LessonStatus lessonStatus = StringHelpers.ConvertStringToEnum<LessonStatus>("prepared");
            ReportStatus reportStatus = StringHelpers.ConvertStringToEnum<ReportStatus>("finished");

            Console.WriteLine(lessonStatus.ToString());
            Console.WriteLine(reportStatus.ToString());
            Console.ReadLine();
        }
    }

    public static class StringHelpers
    {
        public static T ConvertStringToEnum<T>(string text)
        {
            if (Enum.IsDefined(typeof(T), text)) //does not have ignoreCase parameter
                return (T)Enum.Parse(typeof(T), text, true);
            else
                return default(T);
        }
    }

    public enum LessonStatus
    {
        Defined,
        Prepared,
        Practiced,
        Recorded
    }

    public enum ReportStatus
    {
        Draft,
        Revising,
        Finished
    }
}
Run Code Online (Sandbox Code Playgroud)

Dar*_*rov 37

public enum MyEnum
{
    Bar,
    Foo
}

class Program
{
    static void Main(string[] args)
    {
        var containsFoo = Enum.GetNames(typeof(MyEnum)).Any(x => x.ToLower() == "foo");
        Console.WriteLine(containsFoo);
    }
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*ott 29

与@ Darin的答案一样,在.NET 4.0中,Enum类型现在有一个TryParse方法:

MyEnum result;
Enum.TryParse("bar", true, out result);
Run Code Online (Sandbox Code Playgroud)

要记住的重要一点是,Parse与TryParse的行为存在根本区别.解析方法会抛出异常.TryParse方法不会.了解您是否可能尝试解析许多项目非常重要.

  • 这可能会返回字符串化数值的意外结果.即,如果恰好有值为"1"的枚举,则`Enum.TryParse("01",true,out result)`将返回"true".另一方面,达林的答案只会与枚举名称相匹配. (5认同)

sli*_*les 6

Enum.TryParse正如其他人所说,您也许可以仅使用就能摆脱困境。

但是,如果您想要更健壮/更通用的转换,而不是仅转换字符串,则还需要使用Enum.IsDefined,但是不幸的是,如您所见,它区分大小写。

Enum.TryParse (可以)不区分大小写的。但是不幸的是,它允许超出范围的整数通过!

因此解决方案是将它们一起使用(顺序很重要)。

我写了一个扩展方法来做到这一点。它允许从字符串,int / int?和任何其他Enum / Enum?转换。像这样输入:

string value1 = "Value1";
Enum2 enum2 = value1.ParseToEnum<Enum2>();
Debug.Assert(enum2.ToString() == value1);

Enum1 enum1 = Enum1.Value1;
enum2 = enum1.ParseToEnum<Enum2>();
Debug.Assert(enum2.ToString() == enum1.ToString());

int value2 = 1;
enum2 = value2.ParseToEnum<Enum2>();
Debug.Assert(enum2.GetHashCode() == value2);
Run Code Online (Sandbox Code Playgroud)

这是方法的核心。这是回答您问题的转换部分。变量value是类型的,object因为我有“超载”,将不同的类型作为主要输入(请参见上文),但是只要您愿意,就可以使用类型string良好的变量来完成此操作(显然更改value.ToString()为just value)。

if (value != null)
{
    TEnum result;
    if (Enum.TryParse(value.ToString(), true, out result))
    {
        // since an out-of-range int can be cast to TEnum, double-check that result is valid
        if (Enum.IsDefined(typeof(TEnum), result.ToString()))
        {
            return result;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的扩展方法还有很多...它允许您指定默认值,可以很好地处理超出范围的整数,并且完全不区分大小写。如果有人感兴趣,我可以发布更多。


Jus*_*ner 5

请改用Enum.TryParse:

T val;

if(Enum.TryParse(text, true, out val))
    return val;
else 
    return default(T);
Run Code Online (Sandbox Code Playgroud)


cyb*_*rgy 5

我正在使用Compact Framework 3.5,并且:

Enum.TryParse
Run Code Online (Sandbox Code Playgroud)

......不存在.它确实有:

Enum.IsDefined
Run Code Online (Sandbox Code Playgroud)

..但是不支持ignoreCase参数.我想要两全其美,所以想出了这个(作为辅助方法)......

public bool TryParse<TEnum>(string value, bool ignoreCase, ref TEnum result) where TEnum : struct
{
    bool parsed;
    try
    {
        result = (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase);
        parsed = true;
    }
    catch { }
    return parsed;
}
Run Code Online (Sandbox Code Playgroud)

HTH