将字符串解析为枚举类型

发布于 2024-08-04 22:55:31 字数 648 浏览 4 评论 0原文

我有一个像这样的枚举类型作为示例:

public Enum MyEnum {
    enum1, enum2, enum3 };

我将从配置文件中读取一个字符串。我需要的是将字符串解析为 MyEnum 类型或 null 或未定义。不确定以下代码是否有效(很抱歉现在无法访问我的 VS):

// example: ParseEnum<MyEnum>("ENUM1", ref eVal);
bool ParseEnum<T>(string value1, ref eVal) where T : Enum
{
  bool bRet = false;
  var x = from x in Enum.GetNames(typeof(T)) where 
       string.Equals(value1, x, StringComparison. OrdinalIgnoreCase)
       select x;
  if (x.Count() == 1 )
  {
    eVal = Enum.Parse(typeof(T), x.Item(0)) as T;
    bRet = true;
  }
  return bRet;
}

不确定它是否正确或是否有其他简单的方法将字符串解析为 MyEnum 值?

I have an enum type like this as an example:

public Enum MyEnum {
    enum1, enum2, enum3 };

I'll read a string from config file. What I need is to parse the string to MyEnum type or null or not defined. Not sure if the following code will work (sorry for not having access to my VS right now):

// example: ParseEnum<MyEnum>("ENUM1", ref eVal);
bool ParseEnum<T>(string value1, ref eVal) where T : Enum
{
  bool bRet = false;
  var x = from x in Enum.GetNames(typeof(T)) where 
       string.Equals(value1, x, StringComparison. OrdinalIgnoreCase)
       select x;
  if (x.Count() == 1 )
  {
    eVal = Enum.Parse(typeof(T), x.Item(0)) as T;
    bRet = true;
  }
  return bRet;
}

Not sure if it is correct or there is any other simple way to parse a string to a MyEnum value?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

爱*していゐ 2024-08-11 22:55:31

怎么样:

public static class EnumUtils
{
    public static Nullable<T> Parse<T>(string input) where T : struct
    {
        //since we cant do a generic type constraint
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("Generic Type 'T' must be an Enum");
        }
        if (!string.IsNullOrEmpty(input))
        {
            if (Enum.GetNames(typeof(T)).Any(
                  e => e.Trim().ToUpperInvariant() == input.Trim().ToUpperInvariant()))
            {
                return (T)Enum.Parse(typeof(T), input, true);
            }
        }
        return null;
    }
}

用作:(

MyEnum? value = EnumUtils.Parse<MyEnum>("foo");

注意:旧版本在 Enum.Parse 周围使用 try/catch

What about something like:

public static class EnumUtils
{
    public static Nullable<T> Parse<T>(string input) where T : struct
    {
        //since we cant do a generic type constraint
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("Generic Type 'T' must be an Enum");
        }
        if (!string.IsNullOrEmpty(input))
        {
            if (Enum.GetNames(typeof(T)).Any(
                  e => e.Trim().ToUpperInvariant() == input.Trim().ToUpperInvariant()))
            {
                return (T)Enum.Parse(typeof(T), input, true);
            }
        }
        return null;
    }
}

Used as:

MyEnum? value = EnumUtils.Parse<MyEnum>("foo");

(Note: old version used try/catch around Enum.Parse)

无名指的心愿 2024-08-11 22:55:31
private enum MyEnum
{
    Enum1 = 1, Enum2 = 2, Enum3 = 3, Enum4 = 4, Enum5 = 5, Enum6 = 6, 
    Enum7 = 7, Enum8 = 8, Enum9 = 9, Enum10 = 10
}

private static Object ParseEnum<T>(string s)
{
    try
    {
        var o = Enum.Parse(typeof (T), s);
        return (T)o;
    }
    catch(ArgumentException)
    {
        return null;
    }
}

static void Main(string[] args)
{
   Console.WriteLine(ParseEnum<MyEnum>("Enum11"));
   Console.WriteLine(ParseEnum<MyEnum>("Enum1"));
   Console.WriteLine(ParseEnum<MyEnum>("Enum6").GetType());
   Console.WriteLine(ParseEnum<MyEnum>("Enum10"));
}

输出:

    //This line is empty as Enum11 is not there and function returns a null
Enum1
TestApp.Program+MyEnum
Enum10
Press any key to continue . . .
private enum MyEnum
{
    Enum1 = 1, Enum2 = 2, Enum3 = 3, Enum4 = 4, Enum5 = 5, Enum6 = 6, 
    Enum7 = 7, Enum8 = 8, Enum9 = 9, Enum10 = 10
}

private static Object ParseEnum<T>(string s)
{
    try
    {
        var o = Enum.Parse(typeof (T), s);
        return (T)o;
    }
    catch(ArgumentException)
    {
        return null;
    }
}

static void Main(string[] args)
{
   Console.WriteLine(ParseEnum<MyEnum>("Enum11"));
   Console.WriteLine(ParseEnum<MyEnum>("Enum1"));
   Console.WriteLine(ParseEnum<MyEnum>("Enum6").GetType());
   Console.WriteLine(ParseEnum<MyEnum>("Enum10"));
}

OUTPUT:

    //This line is empty as Enum11 is not there and function returns a null
Enum1
TestApp.Program+MyEnum
Enum10
Press any key to continue . . .
枯寂 2024-08-11 22:55:31

这是一个老问题,但现在 .NET 4.5 有 Enum.TryParse()

This is an old question, but now .NET 4.5 has Enum.TryParse<TEnum>().

数理化全能战士 2024-08-11 22:55:31

我在 UnconstrainedMelody 中有一个 TryParseName 方法,这是一个用于委托和枚举实用程序方法通过一些构建后技​​巧使用“无法表达的”约束。 (使用该库的代码不需要后期构建,只是为了清楚起见。)

您可以像这样使用它:

Foo foo;
bool parsed = Enums.TryParseName<Foo>(name, out foo);

我目前没有不区分大小写的版本,但我可以轻松地引入一个如果你愿意的话。请注意,这个不会像内置版本那样尝试解析数字,例如“12”,也不会尝试解析以逗号分隔的标志列表。我可能会在稍后添加标志版本,但我在数字版本中看不到太多意义。

这是在没有装箱和执行时类型检查的情况下完成的。拥有约束真的很方便:)

如果您发现不区分大小写的解析有用,请告诉我......

I have a TryParseName method in UnconstrainedMelody, a library for delegate and enum utility methods which uses "inexpressible" constraints via some postbuild trickery. (Code using the library doesn't need a postbuild, just to be clear.)

You would use it like this:

Foo foo;
bool parsed = Enums.TryParseName<Foo>(name, out foo);

I don't currently have a case-insensitive version, but I could easily introduce one if you wanted. Note that this doesn't try to parse numbers e.g. "12" like the built-in version does, nor does it try to parse comma-separated lists of flags. I may add the flags version later on, but I can't see much point in the numeric version.

This is done without boxing and without execution time type checking. Having the constraint is really handy :)

Please let me know if you'd find a case-insensitive parse useful...

半葬歌 2024-08-11 22:55:31

如果您使用 .NET 3.5(甚至 2.0,如果您删除扩展方法),我对本文中的技术非常幸运:

枚举和字符串 - 停止疯狂!

编辑:域已经消失,现在是一个链接场。我在工作时从我们的代码库中提取了代码(稍作修改并随着时间的推移添加),您现在可以在这里找到:

https://gist.github.com/1305566

If you're using .NET 3.5 (or even 2.0, if you trim out the extension method), I've had great luck with the techniques in this article:

Enumerations and Strings - Stop the Madness!

EDIT: Domain is gone and is now a link farm. I pulled the code (slightly modified and added to over time) from our codebase at work, which you can now find here:

https://gist.github.com/1305566

夏花。依旧 2024-08-11 22:55:31

如果您想避免使用 try/catch,可以使用 TryParse

MyEnum eVal;
if (Enum.TryParse("ENUM2", true, out eVal)){
    // now eVal is the enumeration element: enum2 
}
//unable to parse. You can log the error, exit, redirect, etc...

我对所选答案进行了一些修改。我希望你喜欢它。

public static class EnumUtils
{
    public static Nullable<T> Parse<T>(string input) where T : struct
    {
        //since we cant do a generic type constraint
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("Generic Type 'T' must be an Enum");
        }

        int intVal;
        if (!string.IsNullOrEmpty(input) && !int.TryParse(input, out intVal))
        {
            T eVal;
            if (Enum.TryParse(input, true, out eVal))
            {
                return eVal;
            }
        }
        return null;
    }
}

You can use TryParse if you want to avoid using try/catch.

MyEnum eVal;
if (Enum.TryParse("ENUM2", true, out eVal)){
    // now eVal is the enumeration element: enum2 
}
//unable to parse. You can log the error, exit, redirect, etc...

I modified the selected answer a little bit. I hope you like it.

public static class EnumUtils
{
    public static Nullable<T> Parse<T>(string input) where T : struct
    {
        //since we cant do a generic type constraint
        if (!typeof(T).IsEnum)
        {
            throw new ArgumentException("Generic Type 'T' must be an Enum");
        }

        int intVal;
        if (!string.IsNullOrEmpty(input) && !int.TryParse(input, out intVal))
        {
            T eVal;
            if (Enum.TryParse(input, true, out eVal))
            {
                return eVal;
            }
        }
        return null;
    }
}
新雨望断虹 2024-08-11 22:55:31

我刚刚组合了 此处,异常处理来自 此处,创建这个:

public static class Enum<T>
{
    public static T Parse(string value)
    {
        //Null check
        if(value == null) throw new ArgumentNullException("value");
        //Empty string check
        value = value.Trim();
        if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value");
        //Not enum check
        Type t = typeof(T);
        if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "TEnum");

        return (T)Enum.Parse(typeof(T), value);
    }
}

你可以稍微调整它以返回 null 而不是抛出异常。

I have just combined the syntax from here, with the exception handling from here, to create this:

public static class Enum<T>
{
    public static T Parse(string value)
    {
        //Null check
        if(value == null) throw new ArgumentNullException("value");
        //Empty string check
        value = value.Trim();
        if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value");
        //Not enum check
        Type t = typeof(T);
        if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "TEnum");

        return (T)Enum.Parse(typeof(T), value);
    }
}

You could twiddle it a bit to return null instead of throwing exceptions.

套路撩心 2024-08-11 22:55:31

通过字符串返回 Enum,如果包含:

    public static T GetEnum<T>(string s)
    {
        Array arr = Enum.GetValues(typeof(T));
        foreach (var x in arr)
        {
            if (x.ToString().Contains(s))
                return (T)x;
        }
        return default(T);
    }

To return Enum by string, if contains:

    public static T GetEnum<T>(string s)
    {
        Array arr = Enum.GetValues(typeof(T));
        foreach (var x in arr)
        {
            if (x.ToString().Contains(s))
                return (T)x;
        }
        return default(T);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文