将值解析为可空枚举。

15

假设我有这个:

PriorityType? priority;
string userInput = ...;

我无法更改这个定义:PriorityType? priority,因为它实际上是与另一段代码的合同的一部分。

我尝试过这个,但它不起作用:

if (Enum.TryParse<PriorityType?>(userInput, out priority)) {

什么是正确的方式?


3
你不能创建一个临时的“PriorityType”,然后在解析它之后将其赋值给“priority”吗? - Ron Beyer
可以,我只是想也许有更好的方法。将此作为答案发布,如果没有更好的方法,那么我会接受您的答案。 :) - core
我认为没有。TEnum泛型参数被设置为where TEnum: struct - Bradford Dillon
4个回答

20

如果你想让它只是一行代码,你可以这样做:

var priority = Enum.TryParse<PriorityType>(userInput, out var outPriority) ? outPriority : (PriorityType?) null;

9
最简单的方法是:
PriorityType tempPriority;
PriorityType? priority;

if (Enum.TryParse<PriorityType>(userInput, out tempPriority))
    priority = tempPriority;

这是我能想到的最好翻译:

这是我能想到的最好翻译:

public static class NullableEnum
{
    public static bool TryParse<T>(string value, out T? result) where T :struct, IConvertible
    {
        if (!typeof(T).IsEnum)
            throw new Exception("This method is only for Enums");

        T tempResult = default(T);

        if (Enum.TryParse<T>(value, out tempResult))
        {
            result = tempResult;
            return true;
        }

        result = null;
        return false;
    }
}

使用:

if (NullableEnum.TryParse<PriorityType>(userInput, out priority))

上述类可以像Enum.TryParse一样使用,只是它接受可空输入。如果您想要在两种情况下使用它,可以添加另一个重载函数,该函数接受非可空的T。不幸的是,扩展方法在枚举类型上的效果不太好(根据我短时间的尝试)。


4

这是同样的解决方案,由Ron Beyer发布,并进行了一些重构:

 public static class NullableEnum
{
    public static bool TryParse<T>(string value, out T? result) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum) throw new ArgumentException("Invalid Enum");

        result = Enum.TryParse(value, out T tempResult) ? tempResult : default(T?);

        return (result == null) ? false : true;
    }
}

功能正常,但我想知道为什么如果只使用“default”(而不是“vs default(T?)”),它就无法工作。 - Dylan Nicholson

0

这里还有另一种方法,实际上可以处理可空枚举,而不是在获取它们时失败:

public static class EnumHelper {

    public static TEnum Parse<TEnum>( string value ){
        if( typeof(TEnum).IsEnum )
            return (TEnum)Enum.Parse( typeof(TEnum), value );

        Type? nullableType = Nullable.GetUnderlyingType( typeof(TEnum) );
        if( /*not a nullable type*/nullableType is null )
            throw new ArgumentException( $"Provided type {typeof(TEnum).Name} must be either an enum or a nullable enum" );

        return (TEnum?)Enum.Parse( nullableType, value );
    }

}

调用模式与使用out参数的基本库略有不同,但如果您喜欢,可以将其包装在相同的调用模式中。对于大多数情况来说,上述方法更容易使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接