C#
enums
programming
software development
coding tips

How to get next or previous enum value in C

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

C# enums are named constants, but they do not include built-in navigation methods such as "next" or "previous." If you want that behavior, you usually read the enum values into an ordered array, find the current position, and then decide whether you want wraparound or strict boundary behavior.

Start With the Enum Values

The standard building block is Enum.GetValues, which returns the declared values of the enum.

csharp
1using System;
2
3public enum Status
4{
5    New,
6    InProgress,
7    Done
8}
9
10public class Program
11{
12    public static void Main()
13    {
14        var values = Enum.GetValues<Status>();
15        foreach (var value in values)
16        {
17            Console.WriteLine(value);
18        }
19    }
20}

Once you have that array, moving to the next or previous enum value becomes an indexing problem.

Next Value With Wraparound

A common choice is circular navigation, where moving forward from the last enum value returns the first one.

csharp
1using System;
2
3public enum Status
4{
5    New,
6    InProgress,
7    Done
8}
9
10public static class EnumHelpers
11{
12    public static T Next<T>(T value) where T : struct, Enum
13    {
14        var values = Enum.GetValues<T>();
15        var index = Array.IndexOf(values, value);
16        return values[(index + 1) % values.Length];
17    }
18}
19
20public class Program
21{
22    public static void Main()
23    {
24        Console.WriteLine(EnumHelpers.Next(Status.New));
25        Console.WriteLine(EnumHelpers.Next(Status.Done));
26    }
27}

This works well for state cycles, rotating UI modes, or menu selection logic.

Previous Value With Wraparound

The same idea works in reverse.

csharp
1using System;
2
3public static class EnumHelpers
4{
5    public static T Previous<T>(T value) where T : struct, Enum
6    {
7        var values = Enum.GetValues<T>();
8        var index = Array.IndexOf(values, value);
9        return values[(index - 1 + values.Length) % values.Length];
10    }
11}

The extra + values.Length prevents a negative index before the modulo operation.

Boundary-Safe Version Without Wraparound

Sometimes wraparound is the wrong behavior. In that case, return the current value or throw an exception when the caller is already at the boundary.

csharp
1using System;
2
3public static class EnumHelpers
4{
5    public static T NextOrSame<T>(T value) where T : struct, Enum
6    {
7        var values = Enum.GetValues<T>();
8        var index = Array.IndexOf(values, value);
9
10        if (index == values.Length - 1)
11            return value;
12
13        return values[index + 1];
14    }
15}

This is often better for workflows where the enum represents a true linear progression.

Be Careful With Custom Numeric Values

Enums can declare custom underlying values.

csharp
1public enum ErrorLevel
2{
3    Low = 10,
4    Medium = 20,
5    High = 50
6}

Navigation should usually follow declaration order or the array returned by Enum.GetValues, not assume that current + 1 is valid. Numeric arithmetic on enum values is rarely the right answer unless the enum was explicitly designed to be sequential.

Flags Enums Are a Different Problem

If the enum uses [Flags], next and previous usually stop making sense because combined values such as Read | Write are not part of a simple linear list.

csharp
1[Flags]
2public enum Permission
3{
4    Read = 1,
5    Write = 2,
6    Execute = 4
7}

For flags enums, treat the problem as bit manipulation rather than next/previous navigation.

A Reusable Extension Method

If this pattern appears often in your codebase, an extension method keeps call sites cleaner.

csharp
1using System;
2
3public static class EnumExtensions
4{
5    public static T Next<T>(this T value) where T : struct, Enum
6    {
7        var values = Enum.GetValues<T>();
8        var index = Array.IndexOf(values, value);
9        return values[(index + 1) % values.Length];
10    }
11}

Then you can call:

csharp
var next = Status.New.Next();

Common Pitfalls

The biggest pitfall is assuming enum values are always consecutive integers. C# allows gaps and custom numeric assignments, so value + 1 is not a reliable navigation strategy.

Another issue is forgetting to decide whether wraparound is correct. Circular navigation is convenient, but it can hide bugs if the business rule is actually linear.

Developers also apply the same logic to [Flags] enums even though those represent combinable bit fields rather than an ordered sequence.

Finally, avoid recomputing the value array in extremely hot code paths if performance matters. For normal application logic it is fine, but reusable caches can help in tight loops.

Summary

  • Use Enum.GetValues<T>() to obtain the enum's ordered values.
  • Find the current index, then compute the next or previous position explicitly.
  • Decide whether wraparound or boundary-safe behavior is correct for the use case.
  • Do not rely on numeric + 1 unless the enum was intentionally designed for that.
  • Treat [Flags] enums as a separate bitmask problem, not as a next-value sequence.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.