可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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):
// 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?
回答1:
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)
回答2:
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 . . .
回答3:
This is an old question, but now .NET 4.5 has Enum.TryParse().
http://msdn.microsoft.com/en-us/library/dd991317.aspx
回答4:
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...
回答5:
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
回答6:
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.
回答7:
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; } }
回答8:
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); }