38

我正在尝试构建从用户字符串获取的通用函数并尝试将其解析为 Enum valuse,如下所示:

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);
        }
    }

但我得到:

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)    .

错误意味着我需要为 resultInputType 声明一个特定的枚举?我怎样才能解决这个问题 ?谢谢。

4

6 回答 6

61

TryParse方法具有以下签名:

TryParse<TEnum>(string value, bool ignoreCase, out TEnum result)
    where TEnum : struct

TEnum它有一个必须是结构的泛型类型参数,用于确定要解析的枚举类型。当您没有明确提供它时(就像您所做的那样),它将采用您提供的任何类型作为result参数,在您的情况下是类型Enum(而不是枚举本身的类型)。

请注意,这Enum是一个(尽管它继承自ValueType),因此它不满足TEnum作为struct的要求。

您可以通过删除Type参数并为方法提供具有与函数struct上的泛型类型参数相同的约束(即)的泛型类型参数来解决此问题TryParse

所以试试这个,我在这里命名了泛型类型参数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;
}

要调用该方法,请使用:

GetEnumStringEnumType<MyEnum>();
于 2012-05-21T13:07:48.137 回答
7

您应该制作一个通用方法:

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;
    }

用法:

public enum myEnum { val1, val2 }

myEnum enumValue = getEnumStringEnumType<myEnum>();
于 2012-05-21T13:08:47.353 回答
5

很久以前,在 Visual Studio 2005 时代,我为 Enum 上的 TryParse 创建了自己的方法。我最近才发现 2008 年的实现,我对它的限制性不满意,特别是考虑到它是一个TRY PARSE方法;意味着程序员正在测试输入!

一般来说,我更喜欢使用信任程序员知道他在做什么的方法:)

我的实现如下:

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;
}

缺少 where T:struct 将信任置于开发人员手中,但它允许您使用未知的通用枚举进行编译。

作为替代方案,如果您想在转换为指定的枚举时进行整数比较,则可以在 Enum.GetValues 上创建一个循环方法。

希望这可以帮助。

于 2012-07-17T11:46:55.407 回答
1

Enum.TryParse是一个泛型方法,这意味着它的泛型类型参数必须在编译时知道。这反过来意味着是的,您必须声明resultInputType特定的枚举类型才能编译代码。

如果您考虑一下,原始代码有点过于乐观:它没有说明应该检查哪个userInputString枚举类型以查找名称等于的成员。没有这些信息怎么可能TryParse工作?

于 2012-05-21T13:07:24.687 回答
1

从 C# 7 开始,我们可以将泛型类型指定为Enum

where TCustomValidatorsEnum : Enum

如评论

TryParse<TEnum>(string value, bool ignoreCase, out TEnum result)
    where TEnum : struct

将按照 OP 中的说明进行编译投诉:

类型“System.Enum”必须是不可为空的值类型,以便在泛型类型或方法“System.Enum.TryParse(string, bool, out TEnum) 中将其用作参数“TEnum”

这个版本虽然编译:

var converted = Enum.TryParse(typeof(TCustomValidatorsEnum), schemaConstraintType, true, out var customValidationEnum);
于 2021-08-22T08:34:03.967 回答
0

字符串扩展方法

public TEnum ToEnum<TEnum>(this string value, TEnum defaultValue){

if (string.IsNullOrEmpty(value))return defaultValue;

return Enum.Parse(typeof(TEnum), value, true);}
于 2019-05-22T07:18:45.713 回答