2017-10-06 64 views
2

我最近在JVM/Groovy領域上幾年後回到了.NET世界。類型安全的枚舉模式在C#版本6+中仍然可行

我在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")); 
} 

我organizatoin目前正在使用C#6,而C#7正在成爲害得我幾個問題更爲普遍。

  1. 什麼是類型安全枚舉模式的當前視圖?
  2. 它仍然是一個有效的模式,特別是關於 序列化/持久性?
  3. 我應該放棄它來支持別的嗎?
+0

鏈接是也許不是最權威的,但我認爲這說明了模式以及 – Fontanka16

+2

從我透視圖,如果你想把枚舉引入下一層,最好把它們建模爲值對象或枚舉類。我知道它在第一眼看起來很奇怪,但至少你可以看一下:https://lostechies.com/jimmybogard/2008/08/12/enumeration-classes/ –

+2

我以前使用過這種模式,但是我不要真的把它們視爲「枚舉」。在即將到來的語言版本中,我沒有看到任何提供這種功能的東西,所以它似乎仍然是一種有效的模式。 –

回答

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

你應該清楚'nameof'來自'c#6' –

2

這取決於你想用枚舉做什麼。

在你的榜樣,你要檢查的情況下,或許是一個擴展方法會像這樣是適當的:

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

這將允許你使用它,像這樣:

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

要回答您的問題:

  • 類型安全的枚舉模式在某些情況下仍然有效,您可能不會w螞蟻擴展方法或其他方法。
  • 序列化最好通過屬性完成,但任何情況都需要根據具體情況進行 - 這太籠統了,不能提供一攬子建議。
  • 只有在有清楚的情況下才放棄它,例如新的語言特徵等。當真的使用任何模式時,這是成立的。