C# 将字符串解析为枚举类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1424971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Parse string to enum type
提问by David.Chu.ca
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 it to parse the string to MyEnum type or null o not defined. Not sure if the following codes will work (sorry for not having access to my VS right now):
我将从配置文件中读取一个字符串。我需要它将字符串解析为 MyEnum 类型或 null o 未定义。不确定以下代码是否有效(抱歉现在无法访问我的 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;
}
Not sure if it is correct or there is any other simple way to parse a string to MyEnum value?
不确定它是否正确或有任何其他简单的方法可以将字符串解析为 MyEnum 值?
采纳答案by Rex M
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
)
(注意:try/catch
周围使用的旧版本Enum.Parse
)
回答by TheVillageIdiot
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 . . .
回答by Chris Doggett
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:
如果您使用的是 .NET 3.5(甚至 2.0,如果您去掉扩展方法),我很幸运地使用了本文中的技术:
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:
编辑:域消失了,现在是一个链接农场。我在工作时从我们的代码库中提取了代码(稍作修改并随着时间的推移添加),您现在可以在这里找到:
回答by Jon Skeet
I have a TryParseName
method in UnconstrainedMelody, a library for delegate and enum utility methods which uses "inexpressible" constraints via some postbuild trickery. (Code usingthe library doesn't need a postbuild, just to be clear.)
我TryParseName
在UnconstrainedMelody 中有一个方法,这是一个用于委托和枚举实用程序方法的库,它通过一些后期构建技巧使用“无法表达”的约束。(使用库的代码不需要后期构建,只是为了清楚。)
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'ttry 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.
我目前没有不区分大小写的版本,但如果您愿意,我可以轻松地介绍一个。请注意,这不会像内置版本那样尝试解析数字,例如“12”,也不会尝试解析逗号分隔的标志列表。稍后我可能会添加标志版本,但我在数字版本中看不到太多意义。
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...
如果您发现不区分大小写的解析有用,请告诉我...
回答by Benjol
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.
您可以稍微调整一下以返回 null 而不是抛出异常。
回答by Jaider
You can use TryParse
if you want to avoid using try/catch.
TryParse
如果您想避免使用 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;
}
}
回答by iheartcsharp
This is an old question, but now .NET 4.5 has Enum.TryParse().
这是一个老问题,但现在 .NET 4.5 有 Enum.TryParse()。
回答by Rovann Linhalis
To return Enum by string, if contains:
要按字符串返回 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);
}