using System.Collections.Generic;
public virtual Action<string> GetTokenHandler() => (s) => Console.WriteLine(s);
public sealed class State : IState
private State(string state) => this.state = state;
public static State Initial { get; } = new State(nameof(Initial));
public static State Final { get; } = new State(nameof(Final));
public static State Error { get; } = new State(nameof(Error));
public override string ToString() => state;
public record class StateA(string Token, int Count) : IState
public Action<string> GetTokenHandler() => (s) => Console.WriteLine("The current count is {0} and the current token is {1}", Count, Token);
public record class StateB(string Token) : IState;
const string terminalString = "stop";
IEnumerator<string> inputs = Enumerable.Range(1, 6).Select(i => "token " + i.ToString()).Concat(new [] {terminalString}).GetEnumerator();
string terminalString = "stop";
(int count, IState state) = (0, State.Initial);
while (state != State.Final && state != State.Error)
string token = GetNextToken();
state.GetTokenHandler()(token);
Console.WriteLine("State = {0}", state);
_ when count > maxIterations =>
State s when s == State.Initial =>
StateA s when s is { Count : > 3 } =>
s with { Token = token, Count = s.Count + 1 },
StateB s when s.Token == terminalString =>
s with { Token = token },
_ => throw new Exception($"Unknown state {state}"),
Console.WriteLine("State = {0}", state);
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}\n", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);