【问题标题】:Extension method for nullable Enum from string字符串中可空枚举的扩展方法
【发布时间】:2020-09-21 21:28:43
【问题描述】:

我正在通过下面的代码将一个类的 Enum 转换为另一个类的 Enum:

var someClassA.MyEnumA = (MyEnumA)Enum.Parse(typeof(MyEnumA), someClassB.MyEnumA.ToString());

我发现自己经常重复这段代码,所以我写了一个如下的辅助方法:

    public static T EnumFromString<T>(string value)
    {
        return (T)Enum.Parse(typeof(T), value);
    }

那么上面同一行的用法是:

var someClassA.MyEnumA = EnumFromString<MyEnumA>(someClassB.MyEnumA.ToString());

这很好用。但是,我现在有了可以拥有可为空枚举的代码。所以我目前的代码是:

                if (someClassB.MyEnumX.HasValue)
                {
                    someClassA.MyEnumX = (MyEnumX)Enum.Parse(typeof(MyEnumX),someClassB.MyEnumX.ToString());
                }

我不确定如何更新我当前的辅助方法来处理这两种情况 - 或者只编写另一个名为 NullableEnumFromString 的辅助方法会更简单 - 我不确定泛型如何工作甚至可能实现?

【问题讨论】:

  • 我有点困惑。 SomeClassA 中的 MyEnumA 和 SomeClassB 中的 MyEnumA 属性是什么类型?
  • 你不能在你的辅助方法中检查value并在string.IsNullOrEmpty(value)返回null吗?
  • 要处理可以为空的枚举,您需要使用 &lt;T?&gt; 类型和约束 where T : struct
  • 另外(除了其他 cmets)你还必须从概念上弄清楚你想用 null 做什么?那个地图怎么样?您是要使用默认值,还是要指定默认值。
  • 为什么不改用someClassA.MyEnumX = someClassB.MyEnumX;?为什么需要通过字符串映射?

标签: c# .net generics enums


【解决方案1】:

在我看来,这里的主要问题是,当您调用转换方法时,您已经将枚举值转换为string,因此您无法知道原始类型是什么,没关系处理可以为空的枚举类型。

从让所有呼叫者都必须自己拨打ToString()的角度来看,这对我来说似乎也不方便。

您可以通过编写两种不同的扩展方法来改进这两个方面,一种用于常规枚举类型,一种用于可空版本:

public static TResult Convert<T, TResult>(this T value)
    where T : struct, System.Enum
    where TResult : struct, System.Enum
{
    return (TResult)Enum.Parse(typeof(TResult), value.ToString());
}

public static TResult? Convert<T, TResult>(this T? value)
    where T : struct, System.Enum 
    where TResult : struct, System.Enum
{
    return value != null ?
        (TResult?)Enum.Parse(typeof(TResult), value.ToString()) : null;
}

注意事项:

  • 以上使用 C# 7.3 功能,允许对System.Enum 进行约束。如果使用 C# 的早期版本,请忽略它。它仍然可以工作,但不会具有相同程度的编译时类型安全性。
  • 虽然所有四个类型参数约束都指定了struct,但严格来说,这只是第二个可空枚举版本所必需的。在第一个版本中它不会伤害任何东西。我只是为了保持一致而将其放入。
  • 如果输入值为null,则此可空枚举扩展方法返回null。您的问题并未说明在这种情况下您将使用什么值。如果您不打算这样做,您可以使用任何您喜欢的后备。

【讨论】:

    猜你喜欢
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多