Search code examples
c#enumsincrement

C#; How to Loop Through/Wrap Enumerations when Incremented?


Say you have a byte value equal to its max value, so byte aByte = 255;. When you increment a value past its max value, it usually wraps around to its minimum value, so if I were to write Console.WriteLine(++aByte), this would print 0 to the console because it can't exceed its max value.

I would like to have this same effect when it comes to enumerations I create. So let's say this is the code:

using System;

namespace CSharp_Test_003
{
    class Program
    {
        static void Main()
        {
            Console.Title = "Enumerations";

            Season currentSeason = Season.Spring;
            Console.Write($"{currentSeason++} ");
            Console.Write($"{currentSeason++} ");
            Console.Write($"{currentSeason++} ");
            Console.Write($"{currentSeason++} ");
            Console.Write($"{currentSeason++} ");
        }

        private enum Season { Spring = 0, Summer, Autumn, Winter }
    }

Currently this prints out:

Spring Summer Autumn Winter 4

But I would really like it to say "Spring" where there is a "4". If there's a practical way to make this possible I would really love to know.


Solution

  • You can write your own custom enum that works in a similar way

    static void Main()
    {
        Console.Title = "Enumerations";
    
        Season currentSeason = Season.Spring;
        Console.Write($"{currentSeason++} ");
        Console.Write($"{currentSeason++} ");
        Console.Write($"{currentSeason++} ");
        Console.Write($"{currentSeason++} ");
        Console.Write($"{currentSeason++} ");
    }
    
    //private enum Season { Spring = 0, Summer, Autumn, Winter }
    
    public record Season
    {
        public int Id { get; }
        public string Name { get; }
        private static readonly List<Season> _seasons = new();
    
        public static IReadOnlyList<Season> All => _seasons.OrderBy(x => x.Id).ToList();
    
        private Season(int id, string name)
        {
            Id = id;
            Name = name;
            _seasons.Add(this);
        }
    
        public static Season Spring { get; } = new Season(0, nameof(Spring));
        public static Season Summer { get; } = new Season(1, nameof(Summer));
        public static Season Winter { get; } = new Season(3, nameof(Winter));
        public static Season Autumn { get; } = new Season(2, nameof(Autumn));
    
        public override string ToString() => this.Name;
    
        public static implicit operator string(Season season) => season.ToString();
    
        public static Season operator ++(Season season)
        {
            if (season.Id == All.Count - 1)
                return All[0];
    
            return All[season.Id + 1];
        }
    }