如何尝试解析枚举值?
我想编写一个函数,它可以根据 enum
的可能值验证给定值(作为字符串传递)。 如果匹配,它应该返回枚举实例; 否则,它应该返回默认值。
该函数不能在内部使用 try
/catch
,这不包括使用 Enum.Parse
,后者在给定无效参数时会引发异常。
我想使用类似于 TryParse 函数的东西来实现这一点:
public static TEnum ToEnum<TEnum>(this string strEnumValue, TEnum defaultValue)
{
object enumValue;
if (!TryParse (typeof (TEnum), strEnumValue, out enumValue))
{
return defaultValue;
}
return (TEnum) enumValue;
}
I want to write a function which can validate a given value (passed as a string) against possible values of an enum
. In the case of a match, it should return the enum instance; otherwise, it should return a default value.
The function may not internally use try
/catch
, which excludes using Enum.Parse
, which throws an exception when given an invalid argument.
I'd like to use something along the lines of a TryParse
function to implement this:
public static TEnum ToEnum<TEnum>(this string strEnumValue, TEnum defaultValue)
{
object enumValue;
if (!TryParse (typeof (TEnum), strEnumValue, out enumValue))
{
return defaultValue;
}
return (TEnum) enumValue;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
Enum.IsDefined 将完成任务。 它可能不如 TryParse 那样高效,但它无需异常处理即可工作。
值得注意的是:添加了
TryParse
方法在.NET 4.0 中。Enum.IsDefined will get things done. It may not be as efficient as a TryParse would probably be, but it will work without exception handling.
Worth noting: a
TryParse
method was added in .NET 4.0.正如其他人所说,您必须实现自己的
TryParse
。 Simon Mourier 提供了一个完整的实施方案,可以处理所有事情。如果您使用位域枚举(即标志),您还必须处理像
"MyEnum.Val1|MyEnum.Val2"
这样的字符串,它是两个枚举值的组合。 如果您仅使用此字符串调用Enum.IsDefined
,它将返回 false,即使Enum.Parse
正确处理它。更新
正如 Lisa 和 Christian 在评论中提到的,
Enum.TryParse
现在可用于 .NET4 及更高版本中的 C#。MSDN 文档
As others have said, you have to implement your own
TryParse
. Simon Mourier is providing a full implementation which takes care of everything.If you are using bitfield enums (i.e. flags), you also have to handle a string like
"MyEnum.Val1|MyEnum.Val2"
which is a combination of two enum values. If you just callEnum.IsDefined
with this string, it will return false, even thoughEnum.Parse
handles it correctly.Update
As mentioned by Lisa and Christian in the comments,
Enum.TryParse
is now available for C# in .NET4 and up.MSDN Docs
这是
EnumTryParse
的自定义实现。 与其他常见实现不同,它还支持用Flags
属性标记的枚举。Here is a custom implementation of
EnumTryParse
. Unlike other common implementations, it also supports enum marked with theFlags
attribute.最后,您必须围绕
Enum.GetNames
实现此功能:附加说明:
Enum.TryParse
包含在 .NET 4 中。请参见此处 http://msdn.microsoft.com/library/dd991876(VS.100).aspxEnum.Parse
来捕获失败时抛出的异常。 当找到匹配时,这可能会更快,但如果没有找到匹配,则可能会更慢。 根据您正在处理的数据,这可能是也可能不是净改进。编辑:刚刚看到了一个更好的实现,它缓存了必要的信息:http://damieng.com/blog/2010/10/17/enums-better-syntax-improved-performance-and-tryparse-in-net-3 -5
In the end you have to implement this around
Enum.GetNames
:Additional notes:
Enum.TryParse
is included in .NET 4. See here http://msdn.microsoft.com/library/dd991876(VS.100).aspxEnum.Parse
catching the exception thrown when it fails. This could be faster when a match is found, but will likely to slower if not. Depending on the data you are processing this may or may not be a net improvement.EDIT: Just seen a better implementation on this, which caches the necessary information: http://damieng.com/blog/2010/10/17/enums-better-syntax-improved-performance-and-tryparse-in-net-3-5
基于 .NET 4.5
下面的示例代码
参考:http://www.dotnetperls.com/enum-parse
Based on .NET 4.5
Sample code below
Reference : http://www.dotnetperls.com/enum-parse
...
...
我有一个优化的实现,您可以在 UnconstrainedMelody 中使用。 实际上,它只是缓存名称列表,但它是以一种很好的、强类型的、通用约束的方式这样做的:)
I have an optimised implementation you could use in UnconstrainedMelody. Effectively it's just caching the list of names, but it's doing so in a nice, strongly typed, generically constrained way :)
目前还没有开箱即用的 Enum.TryParse。 已在 Connect 上请求此操作(仍然没有 Enum.TryParse )并得到了回应,表明可能包含在 .NET 3.5 之后的下一个框架中。 您现在必须实施建议的解决方法。
There's currently no out of the box Enum.TryParse. This has been requested on Connect (Still no Enum.TryParse) and got a response indicating possible inclusion in the next framework after .NET 3.5. You'll have to implement the suggested workarounds for now.
避免异常处理的唯一方法是使用 GetNames() 方法,我们都知道异常不应该被滥用于常见的应用程序逻辑:)
The only way to avoid exception handling is to use the GetNames() method, and we all know that exceptions shouldn't be abused for common application logic :)
是否允许缓存动态生成的函数/字典?
因为您(似乎)事先不知道枚举的类型,所以第一次执行可能会生成后续执行可以利用的东西。
您甚至可以缓存 Enum.GetNames() 的结果
您是否正在尝试优化 CPU 或内存? 您真的需要吗?
Is caching a dynamically generated function/dictionary permissable?
Because you don't (appear to) know the type of the enum ahead of time, the first execution could generate something subsequent executions could take advantage of.
You could even cache the result of Enum.GetNames()
Are you trying to optimize for CPU or Memory? Do you really need to?
看一下 Enum 类(struct ?)本身。 有一个 Parse 方法,但我不确定 tryparse。
Have a look at the Enum class (struct ? ) itself. There is a Parse method on that but I'm not sure about a tryparse.
正如其他人已经说过的,如果您不使用 Try&Catch,则需要使用 IsDefined 或 GetNames...
这里有一些示例......它们基本上都是相同的,第一个处理可为空枚举。 我更喜欢第二个,因为它是字符串的扩展,而不是枚举......但您可以根据需要混合它们!
As others already said, if you don't use Try&Catch, you need to use IsDefined or GetNames...
Here are some samples...they basically are all the same, the first one handling nullable enums. I prefer the 2nd one as it's an extension on strings, not enums...but you can mix them as you want!
没有 TryParse,因为 Enum 的类型直到运行时才知道。 遵循与 Date.TryParse 方法相同的方法的 TryParse 会在 ByRef 参数上引发隐式转换错误。
我建议做这样的事情:
There is not a TryParse because the Enum's type is not known until runtime. A TryParse that follows the same methodology as say the Date.TryParse method would throw an implicit conversion error on the ByRef parameter.
I suggest doing something like this:
此方法将转换枚举类型:
它检查基础类型并根据它获取名称进行解析。 如果一切失败,它将返回默认值。
This method will convert a type of enum:
It checks the underlying type and get the name against it to parse. If everything fails it will return default value.