Ashif Nataliya
Ashif Nataliya

Reputation: 922

How to associate list with each enum item in c#

I have website to perform match action. I am writing code to restrict some of the action based on current match stage. For example, If first half is current stage then I should restrict direct end match without second half. For each stage, I have multiple restrict stages. Below is my stage enum.

public enum MatchStage
    {
        FirstHalfAssumedStartTime = 1,
        FirstHalfAssumedEndTime = 2,
        SecondHalfAssumedStartTime = 3,
        SecondHalfAssumedEndTime = 4,
        ExtraFirstHalfAssumedStartTime = 5,
        ExtraFirstHalfAssumedEndTime = 6,
        ExtraSecondHalfAssumedStartTime = 7,
        ExtraSecondHalfAssumedEndTime = 8,
        PauseStartTime = 9,
        PauseEndTime = 10,
        EndMatchTime = 11
    }

I would like to make below method work. I want to call something like currentSiteCoreStage.RestrictedStages which returns List of restricted stages. How can I achieve this?

public static bool IsProposedStageValid(MatchStage currentSiteCoreStage, MatchStage proposedStage )
        {
            if (currentSiteCoreStage.RestrictedStages.Contains(proposedStage)) // I am hoping to make this work
                return false;
        }

Upvotes: 1

Views: 245

Answers (3)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236208

What you have here is actually state machine. You can create method which defines possible stage transitions for each stage supported by your application. E.g. (of course you don't have to use iterators, you can simply return array of stages from each case block):

public static IEnumerable<MatchStage> GetAvailableStageTransitions(MatchStage stage)
{
    switch (stage)
    {
        case MatchStage.FirstHalfAssumedStartTime:
            yield return MatchStage.FirstHalfAssumedEndTime;
            yield return MatchStage.PauseStartTime;
            yield break;
        case MatchStage.SecondHalfAssumedStartTime:
            yield return MatchStage.SecondHalfAssumedEndTime;
            yield return MatchStage.PauseStartTime;
            yield break;
        // etc
        default:
            throw new NotSupportedException($"Stage {stage} is not supported.");
    }
}

Then checking if proposed stage is available:

GetAvailableStageTransitions(currentSiteCoreStage).Contains(proposedStage)

Depending on complexity of your system you can think about incapsulating state transions and logic realted to each state into state objects. For more details read about State Design Pattern.

Upvotes: 3

haku
haku

Reputation: 4505

One approach is to have a class that knows about your current stage and can generate RestrictedStages based on the current stage. Something like:

public enum Stage
{
    First, Second, Third
}

public class CoreStage
{
    public Stage CurrentStage { get; private set; }

    public IEnumerable<Stage> RestrictedStages { get; private set; }

    public CoreStage(Stage currentStage)
    {
        CurrentStage = currentStage;
        RestrictedStages = GenerateRestrictedStages();
    }

    private IEnumerable<Stage> GenerateRestrictedStages()
    {
        //apply your logic to determine Restricted stages based on current stage.
        return null;
    }
}

Now in your IsProposedStageValid method would look sth like below:

public static bool IsProposedStageValid(Stage currentSiteCoreStage, Stage proposedStage)
    {
        var coreStage = new CoreStage(currentSiteCoreStage);
        if (coreStage.RestrictedStages.Contains(proposedStage))
        {
            //do whatever you want.
        }
        return false;
    }

Upvotes: 0

daniell89
daniell89

Reputation: 2272

Maybe consider something like this: 1: Your enum

2:

public class Stage
{
    public MatchStage MathStage { get; set; }
    public List<MatchStage> PossibleStages { get; set; }
}

3.

public static bool IsProposedStageValid(Stage currentSiteCoreStage, MatchStage proposedStage)
{
     if (currentSiteCoreStage.PossibleStages.Contains(proposedStage)) // I am hoping to make this work
     return false;

     return true;
}

Example:

Stage st1 = new Stage
{
      MathStage = MatchStage.FirstHalfAssumedStartTime,
      PossibleStages = new List<MatchStage> { MatchStage.FirstHalfAssumedEndTime }
};

bool res = IsProposedStageValid(st1, MatchStage.PauseEndTime);

Upvotes: 0

Related Questions