将值解析为可空的枚举

时间:2015-10-23 20:52:33

标签: c# enums nullable

我们说我有这个:

PriorityType? priority;
string userInput = ...;

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

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

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

正确的方法是什么?

4 个答案:

答案 0 :(得分:4)

最简单的方法:

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的重载函数,以便您可以在两个实例中使用它(如果需要)。不幸的是,扩展方法在枚举类型上不能很好地工作(据我尝试在短时间内尝试操作它)。

答案 1 :(得分:1)

如果希望将其作为一行代码,则可以这样做:

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

答案 2 :(得分:0)

这是由same solution发布的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;
    }
}

答案 3 :(得分: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 参数的基础库略有不同,但如果您愿意,可以将其包装在相同的调用模式中。在大多数情况下,以上往往更容易使用。