c#中的泛型枚举字符串值解析器

本文关键字:字符串 枚举 泛型 | 更新日期: 2023-09-27 17:59:03

我有一个关于从字符串解析枚举的奇怪问题。事实上,我的应用程序需要处理配置文件中少数枚举的解析。然而,我不想为每个枚举类型编写解析例程(因为有很多)。

我面临的问题是,下面的代码显示了一些奇怪的错误-T的类型必须是不可为null的值类型或类似的类型?

如果我使用where T : enum限制T的类型,那么方法体中的所有其他内容(除了if Enum.TryParse语句)都会被下划线标记为错误。

有人能帮我解决这个奇怪的小问题吗?

谢谢,Martin

public static T GetConfigEnumValue<T>(NameValueCollection config,
                                      string configKey, 
                                      T defaultValue) // where T : enum ?
{
    if (config == null)
    {
        return defaultValue;
    }
    if (config[configKey] == null)
    {
        return defaultValue;
    }
    T result = defaultValue;
    string configValue = config[configKey].Trim();
    if (string.IsNullOrEmpty(configValue))
    {
        return defaultValue;
    }
    //Gives me an Error - T has to be a non nullable value type?
    if( ! Enum.TryParse<T>(configValue, out result) )
    {
        result = defaultValue;
    }
    //Gives me the same error:
    //if( ! Enum.TryParse<typeof(T)>(configValue, out result) )  ...
    return result;
}

一个用户请求发布错误的文本(它是在代码时,而不是编译/运行时),所以它是这样的:

类型"T"必须是不可为null的值类型,才能将其用作泛型类型或方法"System"中的参数TEnum。枚举。TryParse(字符串,输出TEnum)'

c#中的泛型枚举字符串值解析器

好吧,考虑到这些信息,我明白Enum.TryParse方法在抱怨什么了。

对方法设置一个通用约束,如下所示:

public static T GetConfigEnumValue<T>(NameValueCollection config, 
                                      string configKey, 
                                      T defaultValue) // where T : ValueType

或者只放置与Enum.TryParse方法相同的约束。

where T : struct, new()

你可以在这里找到这个定义:

http://msdn.microsoft.com/en-us/library/dd783499.aspx

public static T GetConfigEnumValue<T>(NameValueCollection config, string configKey, T defaultValue)
{
    if (config == null)
    {
        return defaultValue;
    }
    if (config[configKey] == null)
    {
        return defaultValue;
    }
    T result = defaultValue;
    string configValue = config[configKey].Trim();
    if (string.IsNullOrEmpty(configValue))
    {
        return defaultValue;
    }
    try
    {
        result = (T)Enum.Parse(typeof(T), configValue, true);
    }
    catch
    {
        result = defaultValue;
    }
    return result;
}

由于C#不允许您执行where T : enum,因此您必须使用where T : struct

请注意,正如迈克尔所建议的那样,有一些方法可以绕过这一限制。