2017-07-19 88 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

相关问题