2017-07-19 85 views
4

我目前正在撰寫一個由展品組成的旅遊軟件程序。這次展覽的對象,在任何給定的點,是在四個州之一,由ExhibitStates枚舉定義:是否有可能限制在C#中的公共枚舉值?

private enum ExhibitState { Ready, Active, Complete, Inactive }; 

對於開發商誰將會設立的展品,只有兩個「啓動」狀態,我希望他們能夠以供選擇:

public enum StartingExhibitState { Ready, Inactive }; 

目前,我有它設置,以便在被初始化,展覽將立即設置其狀態以匹配其起始狀態,就像這樣:

 switch (startingState) { 
      case StartingExhibitState.Ready: 
       SetState(ExhibitState.Ready); 
       break; 
      case StartingExhibitState.Inactive: 
       SetState(ExhibitState.Inactive); 
       break; 
     } 

我發現自己今天想知道這是否是最佳做法。有沒有更好的方法來限制哪些枚舉選項是公開的,哪些是私有的?或者最好是隻有兩個單獨的枚舉?

非常感謝你的時間。

+0

在你的類中限制枚舉值的「設置」不是更容易嗎? – maccettura

+0

您的switch語句的設置方式,您可以簡單地設置狀態,或者爲不想使用的情況設置一次,一次突破它們,並將狀態設置爲默認操作。我也會假設一個國家是否真的可以從非激活狀態切換到完成狀態是邏輯的? – Icepickle

+3

你可以默認爲'Inactive'並提供'SetReady'方法,根本不需要傳遞開始狀態。 –

回答

4

如果創建第二枚舉 - 你的意圖將通過設置方法

public enum ExhibitState 
{ 
    Inactive = 0, 
    Active = 1, 
    Ready = 2, 
    Complete = 3 
}; 

public enum InitialStates 
{ 
    Inactive = ExhibitState.Inactive, 
    Ready = ExhibitState.Ready 
}; 

public void SetInitial(InitialStates state) 
{ 
    SetState((ExhibitState)state); 
} 

的簽名來解釋的很清楚如果你再進一步,你可以添加編譯器的幫助,以防止通過錯誤的值的方法。

public sealed class InitialState 
{ 
    public static readonly InitialState Initial = new InitialState(ExhibitState.Initial); 

    public static readonly InitialState Ready = new InitialState(ExhibitState.Ready); 

    public ExhibitState State { get; }    

    private InitialState(ExhibitState state) 
    { 
     State = state; 
    } 
} 

構造函數製造private阻止從其他地方實例化類。
類別標記爲sealed以防止導出並更改其行爲。

然後你的方法看起來就像

public void SetInitial(InitialState start) 
{ 
    SetState(start.State); 
} 

// use it 
SetInitial(InitialState.Initial); 
SetInitial(InitialState.Ready); 

沒有別的不能順利通過,直到更改InitialState類的代碼。

+1

您的枚舉值不匹配。你應該聲明'public enum InitialStates {Ready,Inactive = 3};',否則'InitialStates.Inactive'將被映射到'ExhibitState.Active'。 –

+5

你可以明確指出:'public enum InitialStates {Ready = ExhibitState.Ready,Inactive = ExhibitState.Inactive};' –

+0

這就是我現在正在做的。我想知道這是否是最好的方法,或者是否有更簡單的方法。我想這是要走的路。謝謝 – SemperCallide

2

而不是使用枚舉(或兩個),你可以使用基於類的方法:

public abstract class ExhibitState 
{ 
    public static ExhibitInitialState Ready { get { return new ExhibitReadyState(); } } 
    public static ExhibitInitialState Inactive { get { return new ExhibitInactiveState(); } } 
    public static ExhibitState Complete { get { return new ExhibitCompleteState(); } } 
    public static ExhibitState Active { get { return new ExhibitActiveState(); } } 

    private class ExhibitReadyState : ExhibitInitialState {} 
    private class ExhibitInactiveState : ExhibitInitialState {} 
    private class ExhibitCompleteState : ExhibitState {} 
    private class ExhibitActiveState : ExhibitState {} 
} 

public abstract class ExhibitInitialState : ExhibitState {} 

以上示例顯示了一個簡單的方法。通常,您不會在get方法中創建狀態的新實例,但會有靜態實例,以便比較更容易。

與枚舉類似,您仍然可以鍵入ExhibitState.Ready或其他狀態。此外,基類ExhibitInitialState可以限制可最初設置的狀態:

public void SetInitial(ExhibitInitialState initState) { ... } 

相較於@Fabio提出的辦法,你必須,你不能混淆了價值利益。此外,特別是與各州有關的:行爲也應該爲特定狀態而改變的情況非常普遍。通過這種基於類的方法,您可以在特定的ExhibitState實現中實現此行爲,並避免大量可能存在於基於枚舉的方法中的switch語句。

+0

如果你走這條路,考慮不要每次都創建一個新的狀態子類實例。您可以使用C#6(只讀自動屬性)的新語言功能,每次從該類中獲取同一個實例'public static ExhibitInitialState Ready {get;} = new ExhibitReadyState();'。這將使通過平等檢查比較狀態變得更容易,而不必混淆均衡性和哈希值。 –

+0

@BradleyUffner是的,你是對的。我只是想保持簡短的樣本。 – Markus

相關問題