Type#safe Enum模式在C#版本6+中是否仍然可行

时间:2017-10-06 12:42:43

标签: c#

我最近在JVM / Groovy领域几年后回到了.NET世界。

我最喜欢的C#日常模式之一曾是Type-Safe enum pattern,我觉得非常方便。回到C#我立即开始使用它,但现在我怀疑可能有更好或更优选的模式。

让我想到的是我想在“枚举”中引入一些行为。像这样:

public sealed class TypeSafeEnumWithBehaviour
{
    public static readonly TypeSafeEnumWithBehaviour IsLowerCase = new TypeSafeEnumWithBehaviour("IsLowerCase", s => s.All(c => Char.IsLower(c)));
    public static readonly TypeSafeEnumWithBehaviour IsUpperCase = new TypeSafeEnumWithBehaviour("IsUpperCase", s => s.All(c => Char.IsUpper(c)));

    public readonly string Name;
    public readonly Func<string, bool> IsValid;

    private TypeSafeEnumWithBehaviour(string targetName, Func<string, bool> validation)
    {
        Name = targetName;
        IsValid = validation;
    }

}

试验:

[TestMethod]
public void TestMethod1()
{
    Assert.IsTrue(TypeSafeEnumWithBehaviour.IsLowerCase.IsValid("apa"));
    Assert.IsTrue(TypeSafeEnumWithBehaviour.IsUpperCase.IsValid("PAPA"));
}

我的组织机构目前正在使用C#6,但C#7正变得越来越流行,这引发了我几个问题。

  1. 类型安全枚举模式的当前视图是什么?
  2. 它仍然是一个有效的模式,尤其是关于 序列化/ persistation?
  3. 我应该放弃它而不是其他东西吗?

2 个答案:

答案 0 :(得分:3)

C#(从7.1版开始)不支持sum types,因此在解决此问题之前,您提供的链接中描述的模式适用于静态检查的近距离变体的部分解决方案问题。您可以在F#中查看对此的正确语言支持。

您的示例有点奇怪:这些选项并非真正独特的变体。对于"",他们都持有,因为"Aa"他们都没有。它们实际上并没有形成一系列不同的可能性,因此不清楚为什么称它们为枚举。

与C#7语言创新无关的小挑剔:您应该考虑使用nameof这样:

public static readonly TypeSafeEnumWithBehaviour IsLowerCase = new TypeSafeEnumWithBehaviour(nameof(IsLowerCase), s => s.All(c => Char.IsLower(c)));

答案 1 :(得分:2)

这取决于你想要用enum做什么。

在您要检查案例的示例中,可能会使用扩展方法,如下所示:

public static bool IsLowerCase(this Enum value)
{
    return value.ToString() == value.ToString().ToLower();
}

这将允许您像这样使用它:

SomeEnum value = SomeEnums.Test;
if (value.IsLowerCase())
{
    DoSomething();
}

回答你的问题:

  • 在您可能不需要扩展方法或其他方法的某些情况下,类型安全的枚举模式仍然有效。
  • 序列化最好通过属性来完成,但任何实例都需要根据具体情况进行 - 这太笼统而不能提供全面的建议。
  • 只有在明确要求这样做的情况下才放弃它,例如,新的语言功能等。这在真正使用任何模式时都适用。