reflection
constants
programming
type introspection
C#

How can I get all constants of a type by reflection?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, a constant field can be discovered through reflection because it is emitted as metadata on the type. If you want all constants of a particular type, the normal pattern is to read the type's static fields, filter for literal fields, and then filter again for the value type you care about.

What Counts as a Constant in Reflection

For reflection purposes, a C# const field is typically identified with:

  • 'IsLiteral == true'
  • 'IsInitOnly == false'

That distinguishes true compile-time constants from static readonly fields, which are initialized differently and should not be treated as constants in the same way.

Example: Get All String Constants

Here is a complete example that returns all string constants from a type.

csharp
1using System;
2using System.Linq;
3using System.Reflection;
4
5public static class MyConstants
6{
7    public const string Alpha = "A";
8    public const string Beta = "B";
9    public static readonly string NotAConst = "C";
10}
11
12class Program
13{
14    static void Main()
15    {
16        var values = typeof(MyConstants)
17            .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
18            .Where(f => f.IsLiteral && !f.IsInitOnly && f.FieldType == typeof(string))
19            .Select(f => (string)f.GetRawConstantValue()!)
20            .ToArray();
21
22        foreach (var value in values)
23        {
24            Console.WriteLine(value);
25        }
26    }
27}

The key method here is GetRawConstantValue(), which returns the compile-time value stored in metadata.

Why GetRawConstantValue Is the Right API

For constants, GetRawConstantValue() is clearer than trying to read the field like a normal runtime field value. It expresses the real intent: retrieve the constant value recorded in metadata.

That is especially useful when you are reflecting over code for configuration, diagnostics, or generic utility behavior.

Generic Helper Method

You can wrap the logic into a reusable helper.

csharp
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Reflection;
5
6public static class ReflectionHelpers
7{
8    public static IReadOnlyList<T> GetConstantsOfType<T>(Type type)
9    {
10        return type
11            .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
12            .Where(f => f.IsLiteral && !f.IsInitOnly && f.FieldType == typeof(T))
13            .Select(f => (T)f.GetRawConstantValue()!)
14            .ToArray();
15    }
16}

Usage:

csharp
var values = ReflectionHelpers.GetConstantsOfType<string>(typeof(MyConstants));

This is a clean way to reuse the pattern across multiple constant-holder types.

const Versus static readonly

It is important not to confuse these two:

  • 'const values are compile-time constants.'
  • 'static readonly fields are runtime-initialized immutable fields.'

If you include static readonly fields by accident, you are no longer answering the question "get all constants." You are retrieving a different category of static field.

Public Versus Non-Public Constants

If you also need internal or private constants, expand the binding flags accordingly. The reflection pattern stays the same, but the visibility filter changes depending on whether the constants are part of a public API surface or an internal implementation detail.

Inherited constant members deserve the same check.

Common Pitfalls

  • Using reflection over all fields without filtering for literal constant fields.
  • Treating static readonly as if it were the same as const.
  • Forgetting BindingFlags.Static and missing the fields entirely.
  • Using GetValue when GetRawConstantValue() more clearly matches the constant-use case.
  • Assuming inherited constants are included without understanding the chosen binding flags.

Summary

  • In C#, constants can be found with reflection by filtering for literal static fields.
  • The standard checks are IsLiteral, !IsInitOnly, and the target FieldType.
  • 'GetRawConstantValue() is the cleanest API for reading constant values.'
  • 'const and static readonly are not the same thing.'
  • A small helper method makes it easy to retrieve all constants of a given value type.

Course illustration
Course illustration

All Rights Reserved.