Question

Convert an Enum to a List in C#

csharp.netenums

Question

Given a C# enum, how can I create a list containing all values declared by that enum?

For example:

public enum Status
{
    Pending,
    Approved,
    Rejected
}

How can I obtain a List<Status> containing Pending, Approved, and Rejected?

Short Answer

You will learn how C# enums store a fixed set of named values, how to retrieve those values with Enum.GetValues, and how to convert the result into a strongly typed List<T>. You will also learn important details about enum aliases, [Flags] enums, and display-friendly names.

Concept

An enum (enumeration) defines a fixed set of named constants. It is useful when a value must be one of a known set of choices, such as an order status, user role, or payment method.

C# provides Enum.GetValues to retrieve the values declared by an enum type. In modern C#, the generic overload is the clearest option:

Status[] statuses = Enum.GetValues<Status>();

The method returns an array. Since an array and a List<T> are different collection types, use ToList() when a list is specifically required:

List<Status> statuses = Enum.GetValues<Status>().ToList();

This matters because you should not manually maintain a separate list of enum values. If a new member is added to the enum later, Enum.GetValues<Status>() automatically includes it.

Mental Model

Think of an enum as a menu printed by a restaurant:

  • The enum declaration is the official menu.
  • Each enum member is one menu item.
  • Enum.GetValues<Status>() asks for every item currently printed on that menu.
  • ToList() puts those items into a reusable, editable container.

Instead of writing the menu again by hand in another place, read it from the original source of truth: the enum.

Take Quiz

Syntax and Examples

Use Enum.GetValues<TEnum>() to get all values, then call ToList() if you need a list.

using System;
using System.Collections.Generic;
using System.Linq;

public enum Status
{
    Pending,
    Approved,
    Rejected
}

List<Status> statuses = Enum.GetValues<Status>().ToList();

foreach (Status status in statuses)
{
    Console.WriteLine(status);
}

Output:

Pending
Approved
Rejected

Enum.GetValues<Status>() returns a Status[]. ToList() is a LINQ extension method, so include:

using System.Linq;

If you only need to loop through the values, you do not need to create a list:

foreach (Status status in Enum.GetValues<Status>())
{
    Console.WriteLine(status);
}

For older C# or .NET versions that do not support the generic overload, use the type-based overload and cast the result:

List<Status> statuses = Enum.GetValues(typeof(Status))
    .Cast<Status>()
    .ToList();

Step by Step Execution

Consider this code:

public enum Priority
{
    Low,
    Medium,
    High
}

Priority[] priorities = Enum.GetValues<Priority>();
List<Priority> priorityList = priorities.ToList();

Step by step:

  1. Priority declares three possible values: Low, Medium, and High.

  2. Enum.GetValues<Priority>() examines the Priority enum type.

  3. It creates an array containing every declared enum value:

    [Priority.Low, Priority.Medium, Priority.High]
    
  4. The array is assigned to priorities.

  5. priorities.ToList() creates a new List<Priority> with the same items.

  6. priorityList can now use list operations such as Count, indexing, or Add. In most cases, however, you should treat enum options as fixed and avoid adding values that were not declared in the enum.

Real World Use Cases

Common uses for enumerating an enum include:

  • Dropdown menus: Show all supported order statuses in an admin dashboard.
  • API validation: Check whether an incoming value is one of the allowed application states.
  • Configuration screens: Let a user choose a theme, language mode, or notification frequency.
  • Reports: Group records by every possible category, including categories with zero records.
  • Test data: Run the same test against each supported enum value.
  • Command-line tools: Display all available output formats or execution modes.

Example: creating options for a UI model:

public enum ShippingMethod
{
    Standard,
    Express,
    Pickup
}

List<ShippingMethod> options = Enum.GetValues<ShippingMethod>().ToList();
Take Quiz

Real Codebase Usage

In production code, developers often enumerate enums at application boundaries: UI forms, request validation, serialization, and configuration. Keep the enum itself as the source of truth.

Return a read-only collection when callers should not change it

using System;
using System.Collections.Generic;

public static class StatusOptions
{
    public static IReadOnlyList<Status> All { get; } = Array.AsReadOnly(
        Enum.GetValues<Status>()
    );
}

This communicates that callers may read the available options but should not modify the collection.

Validate an enum value

An enum variable can hold a numeric value that was never declared, especially when data comes from an API, database, or integer cast.

public static bool IsValidStatus(Status status)
{
    return Enum.IsDefined(status);
}

Build display data separately

Enum names are often developer-oriented. A UI usually needs a label:

var options = Enum.GetValues<Status>()
    .Select(status => new
    {
        Value = status,
        Label = status.ToString()
    })
    .ToList();

For user-facing labels, many projects use attributes, resource files, or a dedicated mapping method rather than exposing raw enum names directly.

Common Mistakes

Forgetting that GetValues returns an array

This does not compile because the method returns Status[], not List<Status>:

// Broken
List<Status> statuses = Enum.GetValues<Status>();

Convert it explicitly:

List<Status> statuses = Enum.GetValues<Status>().ToList();

Manually duplicating enum members in a list

// Fragile: this becomes outdated when the enum changes.
var statuses = new List<Status>
{
    Status.Pending,
    Status.Approved,
    Status.Rejected
};

Prefer Enum.GetValues<Status>(), which updates automatically when the enum changes.

Using ToString() as a user-friendly label

Console.WriteLine(Status.Pending.ToString()); // "Pending"

This is fine for logs and debugging, but UI text may need spaces, localization, or business wording. Map enum values to display labels deliberately.

Assuming enum values are always sequential

public enum HttpResult
{
    Ok = 200,
    NotFound = 404
}

Do not loop from 0 to a maximum integer. Enum values can have explicit numbers, gaps, negative values, and aliases. Use Enum.GetValues.

Ignoring duplicate numeric values (aliases)

public enum Result
{
    Success = 0,
    Ok = 0,
    Failed = 1
}

Success and Ok represent the same underlying numeric value. Do not assume each returned value is a unique numeric value. If your logic requires unique numeric values, apply Distinct():

List<Result> uniqueValues = Enum.GetValues<Result>()
    .Distinct()
    .ToList();

Treating [Flags] combinations as declared options

A flags enum can represent combinations such as Read | Write. Enum.GetValues returns declared constants, not every possible combination. Generate combinations only when your application genuinely needs them.

Comparisons

ApproachResultBest use
Enum.GetValues<Status>()Status[]Looping over every enum value
Enum.GetValues<Status>().ToList()List<Status>When list-specific APIs are required
Enum.GetNames<Status>()string[]Getting member names rather than values
Enum.GetValues(typeof(Status)).Cast<Status>()Enumerable of StatusOlder C# or .NET codebases
Manual new List<Status> { ... }Hand-maintained listOnly when intentionally showing a subset or custom order

GetValues returns enum values:

Status[] values = Enum.GetValues<Status>();

GetNames returns strings:

string[] names = Enum.GetNames<Status>();

Use values when your program will compare, store, or process the enum. Use names when you specifically need text identifiers.

Take Quiz

Cheat Sheet

using System.Linq;

// All values as an array
Status[] values = Enum.GetValues<Status>();

// All values as a list
List<Status> list = Enum.GetValues<Status>().ToList();

// Loop without allocating a list
foreach (Status value in Enum.GetValues<Status>())
{
    Console.WriteLine(value);
}

// Older type-based syntax
List<Status> oldStyle = Enum.GetValues(typeof(Status))
    .Cast<Status>()
    .ToList();

// Get names instead of values
string[] names = Enum.GetNames<Status>();

// Check whether a value is declared
bool valid = Enum.IsDefined(Status.Pending);

Key rules:

  • Enum.GetValues<TEnum>() returns an array.
  • Call ToList() only when you need a mutable List<T>.
  • Include using System.Linq; for ToList(), Cast(), Select(), and Distinct().
  • Enum numeric values do not have to start at zero or be consecutive.
  • Be careful with aliases and [Flags] enums.

FAQ

How do I get all enum values in C#?

Use Enum.GetValues<TEnum>():

Status[] values = Enum.GetValues<Status>();

How do I convert Enum.GetValues to a List<T>?

Call ToList():

List<Status> values = Enum.GetValues<Status>().ToList();

Why does ToList() not work in my C# code?

ToList() is a LINQ extension method. Add using System.Linq; and ensure your project references the standard LINQ libraries.

Do I need a list to loop through enum values?

No. Loop directly over the array returned by Enum.GetValues<TEnum>().

foreach (Status status in Enum.GetValues<Status>())
{
    Console.WriteLine(status);
}

Does Enum.GetValues include every [Flags] combination?

No. It returns the constants explicitly declared in the enum. Combinations such as Read | Write are not automatically generated.

Can an enum contain duplicate values?

Yes. Multiple member names can use the same underlying number. Treat aliases carefully when displaying or counting values.

Is Enum.GetValues(typeof(MyEnum)) still valid?

Yes. It is useful in older code, but Enum.GetValues<MyEnum>() is clearer and strongly typed in modern C#.

Take Quiz

Mini Project

Description

Create a small console program that displays every available order status and verifies whether an order status received as a number is defined by the enum. This reflects a common boundary in real applications, where values may come from forms, APIs, or databases.

Goal

Enumerate enum values into a list and safely validate a selected status.

Requirements

  1. Define an OrderStatus enum with at least three values.
  2. Create a List<OrderStatus> containing all declared enum values.
  3. Print each available status.
  4. Read a numeric status value from the console.
  5. Report whether the supplied value is a declared OrderStatus.
Take Quiz

Keep learning

Related questions

View more