C# 如何将通用 Tryparse 与 Enum 一起使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10685794/
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
How to use generic Tryparse with Enum?
提问by Rami
I'm trying to build generic function that get from user string and try to parse it to Enum valuse like this:
我正在尝试构建从用户字符串获取的通用函数,并尝试将其解析为 Enum 值,如下所示:
private Enum getEnumStringEnumType(Type i_EnumType)
{
string userInputString = string.Empty;
Enum resultInputType;
bool enumParseResult = false;
while (!enumParseResult)
{
userInputString = System.Console.ReadLine();
enumParseResult = Enum.TryParse(userInputString, true, out resultInputType);
}
}
But i get:
但我得到:
The type 'System.Enum' must be a non-nullable value type in order to use it as parameter 'TEnum' in the generic type or method 'System.Enum.TryParse<TEnum>(string, bool, out TEnum) .
The Error means that i need to decalare a specific Enum for resultInputType? How can I fix this ? Thanks.
错误意味着我需要为 resultInputType 声明一个特定的枚举?我怎样才能解决这个问题 ?谢谢。
采纳答案by Daniel A.A. Pelsmaeker
The TryParsemethodhas the following signature:
该TryParse方法具有以下签名:
TryParse<TEnum>(string value, bool ignoreCase, out TEnum result)
where TEnum : struct
It has a generic type parameter TEnumthat must be a structand that is used to determine the type of enumeration being parsed. When you don't provide it explicitly (as you did), it will take the type of whatever you provide as the resultargument, which in your case is of type Enum(and not the type of the enumeration itself).
它有一个泛型类型参数TEnum,它必须是一个结构体,用于确定被解析的枚举类型。当您没有明确提供它时(如您所做的那样),它将采用您提供的任何类型作为result参数,在您的情况下它是类型Enum(而不是枚举本身的类型)。
Note that Enumis a class(despite it inheriting from ValueType) and therefore it does not satisfy the requirement that TEnumis a struct.
请注意,这Enum是一个类(尽管它继承自ValueType),因此它不满足TEnum作为struct的要求。
You can solve this by removing the Typeparameter and giving the method a generic type parameter with the same constraints (i.e. struct) as the generic type parameter on the TryParsefunction.
您可以通过删除Type参数并为方法提供具有与函数struct上的泛型类型参数相同的约束(即)的泛型类型参数来解决此问题TryParse。
So try this, where I've named the generic type parameter TEnum:
所以试试这个,我已经命名了泛型类型参数TEnum:
private static TEnum GetEnumStringEnumType<TEnum>()
where TEnum : struct
{
string userInputString = string.Empty;
TEnum resultInputType = default(TEnum);
bool enumParseResult = false;
while (!enumParseResult)
{
userInputString = System.Console.ReadLine();
enumParseResult = Enum.TryParse(userInputString, true, out resultInputType);
}
return resultInputType;
}
To call the method, use:
要调用该方法,请使用:
GetEnumStringEnumType<MyEnum>();
回答by Jon
Enum.TryParseis a generic method, which means that its generic type parameters have to be known at compile time. This in turn means that yes, you do have to declare resultInputTypeas a specificenum type for the code to compile.
Enum.TryParse是泛型方法,这意味着必须在编译时知道其泛型类型参数。这反过来意味着是的,您必须声明resultInputType为要编译的代码的特定枚举类型。
If you think on it, the original code is a bit too optimistic: nowhere does it say whichenum type should be checked for a member with name equal to userInputString. How could TryParsework without this information?
如果你仔细想想,原来的代码有点过于乐观了:它没有说明应该检查哪个枚举类型来查找名称等于userInputString. TryParse没有这些信息怎么能工作?
回答by eyossi
You should make a generic method:
您应该创建一个通用方法:
private T getEnumStringEnumType<T>() where T : struct, IConvertible
{
string userInputString = string.Empty;
T resultInputType = default(T);
bool enumParseResult = false;
while (!enumParseResult)
{
userInputString = System.Console.ReadLine();
enumParseResult = Enum.TryParse<T>(userInputString, out resultInputType);
}
return resultInputType;
}
usage:
用法:
public enum myEnum { val1, val2 }
myEnum enumValue = getEnumStringEnumType<myEnum>();
回答by Mark Mintoff
Long ago in Visual Studio 2005 era, I made my own method for TryParse on Enum. I only recently discovered the 2008 implementation and I'm not happy with it's restrictiveness, especially considering that it's a TRY PARSEmethod; meaning that a programmer is testing an input!
很久以前,在 Visual Studio 2005 时代,我在 Enum 上创建了自己的 TryParse 方法。我最近才发现 2008 年的实现,我对它的限制性不满意,特别是考虑到它是一种TRY PARSE方法;这意味着程序员正在测试输入!
Generally, I prefer to use methods which trust the programmer to know what he's doing :)
一般来说,我更喜欢使用相信程序员知道他在做什么的方法:)
My implementation is as follows:
我的实现如下:
public static bool EnumTryParse<T>(string input, out T theEnum)
{
foreach (string en in Enum.GetNames(typeof(T)))
{
if (en.Equals(input, StringComparison.CurrentCultureIgnoreCase))
{
theEnum = (T)Enum.Parse(typeof(T), input, true);
return true;
}
}
theEnum = default(T);
return false;
}
The lack of a where T:struct puts the trust in the developer's hands, but it allows you to compile with unknown, generic enums.
缺乏 where T:struct 将信任放在开发人员的手中,但它允许您使用未知的通用枚举进行编译。
As an alternative, you can create a method looping on Enum.GetValues if you want to do an integer comparison when converting to your specified enum.
作为替代方法,如果您想在转换为指定的枚举时进行整数比较,您可以创建一个在 Enum.GetValues 上循环的方法。
Hope this helps.
希望这可以帮助。
回答by AHMED RABEE
String Extension Method
字符串扩展方法
public TEnum ToEnum<TEnum>(this string value, TEnum defaultValue){
if (string.IsNullOrEmpty(value))return defaultValue;
return Enum.Parse(typeof(TEnum), value, true);}

