🎉 Hooray! After 3 years of work, I've finally released the ebook on design patterns! Check it out »

C#: State

State

State is a behavioral design pattern that allows an object to change the behavior when its internal state changes.

The pattern extracts state-related behaviors into separate state classes and forces original object to delegate the work to an instance of these classes, instead of acting on its own.

Learn more about State

Application of the pattern in C#

Complexity:

Popularity:

Usage examples: The State pattern is commonly used in C# to convert massive switch-base state machines into the objects.

Identification: State pattern can be recognized by methods that change their behavior depending on the objects’ state, controlled externally.

Example: Structure of the Pattern

This example illustrates the structure of the State design pattern. It focuses on answering these questions:

  • What classes does it consists of?
  • What roles do these classes play?
  • In what way the elements of the pattern are related?

Program.cs: Structural Example

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RefactoringGuru.DesignPatterns.State.Structural
{
    class Context
    {
        private State _state = null;

        public Context(State state)
        {
            this.transitionTo(state);
        }

        public void transitionTo(State state)
        {
            Console.Write("Context: Transition to " + state.ToString() + ".\n");
            this._state = state;
            this._state.setContext(this);
        }

        public void request1()
        {
            this._state.handle1();
        }

        public void request2()
        {
            this._state.handle2();
        }
    }
    
    abstract class State
    {
        protected Context context;

        public void setContext(Context context)
        {
            this.context = context;
        }

        public abstract void handle1();

        public abstract void handle2();
    }

    class ConcreteStateA : State
    {
        public override void handle1()
        {
            Console.Write("ConcreteStateA handles request1.\n");
            Console.Write("ConcreteStateA wants to change the state of the context.\n");
            this.context.transitionTo(new ConcreteStateB());
        }

        public override void handle2()
        {
            Console.Write("ConcreteStateA handles request2.\n");
        }
    }

    class ConcreteStateB : State
    {
        public override void handle1()
        {
            Console.Write("ConcreteStateB handles request1.\n");
        }

        public override void handle2()
        {
            Console.Write("ConcreteStateB handles request2.\n");
            Console.Write("ConcreteStateB wants to change the state of the context.\n");
            this.context.transitionTo(new ConcreteStateA());
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Client.ClientCode();
        }
    }

    class Client
    {
        public static void ClientCode()
        {
            var context = new Context(new ConcreteStateA());
            context.request1();
            context.request2();
        }
    }
}

Output.txt: Output

Context: Transition to RefactoringGuru.DesignPatterns.State.Structural.ConcreteStateA.
ConcreteStateA handles request1.
ConcreteStateA wants to change the state of the context.
Context: Transition to RefactoringGuru.DesignPatterns.State.Structural.ConcreteStateB.
ConcreteStateB handles request2.
ConcreteStateB wants to change the state of the context.
Context: Transition to RefactoringGuru.DesignPatterns.State.Structural.ConcreteStateA.