如何使用Enum的通用Tryparse?

时间:2012-05-21 13:04:18

标签: c# generics enums

我正在尝试构建从用户字符串获取的泛型函数,并尝试将其解析为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转换特定的枚举? 我怎样才能解决这个问题 ? 感谢。

5 个答案:

答案 0 :(得分:48)

TryParse method具有以下签名:

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

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

请注意Enum is a class(尽管它继承自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>();

答案 1 :(得分:5)

你应该制作一个通用的方法:

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

答案 2 :(得分:1)

Enum.TryParse是一种通用方法,这意味着必须在编译时知道其泛型类型参数。这反过来意味着是的,你必须将resultInputType声明为特定的枚举类型,以便编译代码。

如果您考虑一下,原始代码有点过于乐观:没有任何地方说应该检查名称等于userInputString的成员的枚举类型。如果没有这些信息TryParse怎么办?

答案 3 :(得分:1)

很久以前在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;
}

缺少一个T:struct将信任放在开发人员手中,但它允许你使用未知的通用枚举进行编译。

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

希望这有帮助。

答案 4 :(得分:0)

字符串扩展方法

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

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

return Enum.Parse(typeof(TEnum), value, true);}