C#
enums
programming
string association
.NET

Associating enums with strings in C

Master System Design with Codemia

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

Introduction

Although the title says C, this question usually appears in a C# or .NET context, where enums are common and developers want readable labels for UI, logs, or API output. An enum stores numeric values, but you can map those values to strings in several ways depending on whether you need simplicity, performance, or localization.

Start with ToString

If the enum member name is already the text you want, use ToString(). It is the simplest option and requires no extra mapping.

csharp
1using System;
2
3enum AccessLevel
4{
5    Guest,
6    User,
7    Moderator,
8    Administrator
9}
10
11class Program
12{
13    static void Main()
14    {
15        AccessLevel level = AccessLevel.Moderator;
16        Console.WriteLine(level.ToString());
17    }
18}

This prints Moderator. That is fine for internal logs or debugging, but it becomes limiting once you need spaces, friendly wording, or translated text.

Use a switch for Explicit Mappings

For small enums, a switch expression is often the clearest approach. It is fast, easy to read, and checked by the compiler.

csharp
1using System;
2
3enum AccessLevel
4{
5    Guest,
6    User,
7    Moderator,
8    Administrator
9}
10
11static class AccessLevelExtensions
12{
13    public static string ToDisplayText(this AccessLevel level) =>
14        level switch
15        {
16            AccessLevel.Guest => "Guest user",
17            AccessLevel.User => "Registered user",
18            AccessLevel.Moderator => "Forum moderator",
19            AccessLevel.Administrator => "System administrator",
20            _ => level.ToString()
21        };
22}
23
24class Program
25{
26    static void Main()
27    {
28        Console.WriteLine(AccessLevel.Administrator.ToDisplayText());
29    }
30}

This is a strong default when the mapping is part of application logic and not meant to be configured externally.

Use Attributes for Metadata

If you want the string to live next to the enum definition, attributes are useful. A common pattern is DescriptionAttribute.

csharp
1using System;
2using System.ComponentModel;
3using System.Reflection;
4
5enum AccessLevel
6{
7    [Description("Guest user")]
8    Guest,
9
10    [Description("Registered user")]
11    User,
12
13    [Description("Forum moderator")]
14    Moderator
15}
16
17static class EnumHelper
18{
19    public static string GetDescription(Enum value)
20    {
21        FieldInfo? field = value.GetType().GetField(value.ToString());
22        DescriptionAttribute? attribute =
23            field?.GetCustomAttribute<DescriptionAttribute>();
24
25        return attribute?.Description ?? value.ToString();
26    }
27}
28
29class Program
30{
31    static void Main()
32    {
33        Console.WriteLine(EnumHelper.GetDescription(AccessLevel.User));
34    }
35}

The advantage is that the mapping stays close to the enum declaration. The tradeoff is that reading the attribute usually uses reflection, which is slightly more complex than a direct switch.

Use a Dictionary for Configurable Mappings

If the strings change often or come from configuration, a dictionary can be a better fit than attributes.

csharp
1using System;
2using System.Collections.Generic;
3
4enum AccessLevel
5{
6    Guest,
7    User,
8    Moderator
9}
10
11class Program
12{
13    static readonly Dictionary<AccessLevel, string> Labels = new()
14    {
15        [AccessLevel.Guest] = "Guest user",
16        [AccessLevel.User] = "Registered user",
17        [AccessLevel.Moderator] = "Forum moderator"
18    };
19
20    static void Main()
21    {
22        Console.WriteLine(Labels[AccessLevel.Guest]);
23    }
24}

This approach works well when the mapping belongs to a specific feature rather than to the enum type itself.

Which Approach Should You Choose

Use ToString() when the enum name already matches the final output. Use a switch when you want explicit, compile-time-safe labels. Use attributes when the display text should live with the enum definition. Use a dictionary when the mapping is feature-specific or may be replaced at runtime.

For localization, do not hard-code every translated string in attributes unless your project is small. In larger applications, enums often map to resource keys, and the UI layer resolves those keys through the localization system.

Common Pitfalls

The biggest pitfall is assuming enum names are user-facing text. PaymentDeclinedByFraudRules may be a good internal identifier, but it is poor UI copy.

Another mistake is forgetting to update the mapping when a new enum value is added. A switch expression helps here because the compiler can warn when you are not handling all members.

Reflection-based attribute lookup can also be overused. It is fine for admin screens or forms, but if you call it in very hot code paths, caching the result is better.

Finally, avoid mixing several mapping styles for the same enum unless there is a clear reason. If one screen uses ToString(), another uses attributes, and a third uses a dictionary, inconsistent labels will creep into the product.

Summary

  • Enums do not store custom strings directly, so you need a mapping strategy.
  • 'ToString() is simplest, but only returns the enum member name.'
  • A switch expression is a clear and fast way to produce friendly labels.
  • Attributes keep display text close to the enum definition.
  • Dictionaries work well when labels are feature-specific or configurable.

Course illustration
Course illustration

All Rights Reserved.