Question
In C#, I have the following enum:
public enum AuthenticationMethod
{
FORMS = 1,
WINDOWSAUTHENTICATION = 2,
SINGLESIGNON = 3
}
I want AuthenticationMethod.FORMS to give me the string "FORMS" instead of the numeric value 1.
I found an approach that uses a custom attribute to store a string value:
public class StringValue : System.Attribute
{
private readonly string _value;
public StringValue(string value)
{
_value = value;
}
public string Value
{
get { return _value; }
}
}
Then the enum is decorated like this:
public enum AuthenticationMethod
{
[StringValue("FORMS")]
FORMS = 1,
[StringValue("WINDOWS")]
WINDOWSAUTHENTICATION = 2,
[StringValue("SSO")]
SINGLESIGNON = 3
}
And a helper method reads the attribute:
public static class StringEnum
{
public static string GetStringValue(Enum value)
{
string output = null;
Type type = value.GetType();
FieldInfo fi = type.GetField(value.ToString());
StringValue[] attrs =
fi.GetCustomAttributes(typeof(StringValue), false) as StringValue[];
if (attrs.Length > 0)
{
output = attrs[0].Value;
}
return output;
}
}
Usage:
string valueOfAuthenticationMethod = StringEnum.GetStringValue(AuthenticationMethod.FORMS);
This works, but it feels like a lot of code for something that seems common. Is there a simpler or better way to get a string representation of an enum in C#?
Short Answer
By the end of this page, you will understand the difference between an enum's name, numeric value, and custom display text in C#. You will learn when ToString() already solves the problem, when attributes are useful, and what patterns are commonly used in real codebases for enum-to-string conversion.
Concept
An enum in C# is a named set of constant values. Each enum member has:
- a name like
FORMS - an underlying numeric value like
1 - optionally, a custom display string like
"Windows"or"SSO"
These are three different things.
The key idea
If you want the enum member name, C# already provides it:
AuthenticationMethod.FORMS.ToString() // "FORMS"
So if your goal is simply to get "FORMS", you do not need a custom attribute, dictionary, or helper class.
Why this matters
Many developers mix up these cases:
- Numeric value needed → cast the enum to
int - Enum name needed → use
ToString() - Custom label needed → use an attribute or mapping
For your example:
AuthenticationMethod.FORMS // enum value
(int)AuthenticationMethod.FORMS // 1
AuthenticationMethod.FORMS.ToString() // "FORMS"
When custom attributes make sense
Your custom attribute approach is useful only when the string you want is different from the enum member name.
For example:
public enum AuthenticationMethod
{
FORMS = 1,
WINDOWSAUTHENTICATION = 2,
SINGLESIGNON = 3
}
If you want:
FORMS→"FORMS"WINDOWSAUTHENTICATION→"WINDOWS"SINGLESIGNON→"SSO"
then ToString() is no longer enough for all values, because ToString() returns the enum member name exactly.
That is the real decision point:
- If the enum name is acceptable, use
ToString(). - If you need a different user-facing string, use metadata such as attributes or a mapping function.
Mental Model
Think of an enum member as a contact card with multiple fields:
- Internal code:
1 - Programmer name:
FORMS - Display label:
Forms Login
Depending on what you ask for, you get a different field:
- cast to
int→ internal code - call
ToString()→ programmer name - use an attribute or mapping → display label
So the main question is not "How do I convert an enum to string?" but rather:
Which string do I actually want?
That question helps you choose the simplest correct approach.
Syntax and Examples
1. Get the enum name with ToString()
public enum AuthenticationMethod
{
FORMS = 1,
WINDOWSAUTHENTICATION = 2,
SINGLESIGNON = 3
}
string name = AuthenticationMethod.FORMS.ToString();
Console.WriteLine(name); // FORMS
Use this when the enum member name is already the exact string you want.
2. Get the numeric value
int id = (int)AuthenticationMethod.FORMS;
Console.WriteLine(id); // 1
Use this when storing or comparing numeric codes.
3. Use a custom mapping when the display text is different
public enum AuthenticationMethod
{
FORMS = 1,
WINDOWSAUTHENTICATION = 2,
SINGLESIGNON = 3
}
public static class AuthenticationMethodExtensions
{
public static string ToDisplayString(this AuthenticationMethod method)
{
return method switch
{
AuthenticationMethod.FORMS => "FORMS",
AuthenticationMethod.WINDOWSAUTHENTICATION => "WINDOWS",
AuthenticationMethod.SINGLESIGNON => "SSO",
_ => method.ToString()
};
}
}
Usage:
string text = AuthenticationMethod.SINGLESIGNON.ToDisplayString();
Console.WriteLine(text); // SSO
This is often simpler than reflection-based attributes when only a few enum values need custom text.
4. Use DescriptionAttribute for display labels
C# also commonly uses built-in attributes such as DescriptionAttribute:
using System.ComponentModel;
public enum AuthenticationMethod
{
[Description("FORMS")]
FORMS = 1,
[Description("WINDOWS")]
WINDOWSAUTHENTICATION = 2,
[Description("SSO")]
SINGLESIGNON = 3
}
You would still need a helper method to read the attribute, but using a standard attribute is often clearer than inventing a custom one.
Step by Step Execution
Consider this code:
public enum AuthenticationMethod
{
FORMS = 1,
WINDOWSAUTHENTICATION = 2,
SINGLESIGNON = 3
}
AuthenticationMethod method = AuthenticationMethod.FORMS;
string name = method.ToString();
int number = (int)method;
What happens step by step
Step 1
AuthenticationMethod method = AuthenticationMethod.FORMS;
The variable method now holds the enum value FORMS.
Internally, its underlying numeric value is 1.
Step 2
string name = method.ToString();
ToString() returns the name of the enum member, not its number.
So:
name == "FORMS"
Step 3
int number = (int)method;
Casting the enum to int gives its numeric value.
So:
number == 1
Important takeaway
The same enum value can produce different outputs depending on how you use it:
Console.WriteLine(method); // FORMS
Console.WriteLine(method.ToString()); // FORMS
Console.WriteLine((int)method); // 1
That is why custom string logic is only needed if the displayed string must differ from the enum member name.
Real World Use Cases
Enums and enum-to-string conversion appear in many practical situations.
Configuration values
public enum EnvironmentType
{
Development,
Staging,
Production
}
You may log or display:
Console.WriteLine(EnvironmentType.Production.ToString());
Authentication and authorization
Your example is a real one:
FORMSWINDOWSAUTHENTICATIONSINGLESIGNON
The enum gives type safety in code, while strings may be needed for logs, config files, UI, or API payloads.
User interface labels
Sometimes enum names are too technical:
WINDOWSAUTHENTICATIONin codeWindowsin the UI
This is where custom labels or attributes are useful.
Serialization and APIs
Some APIs expect strings such as:
{"authenticationMethod":"SSO"}
In that case, you may map enum values to the exact string format required by the API.
Logging and debugging
ToString() is commonly used in logs because enum names are much more readable than numbers:
logger.LogInformation("Selected method: {Method}", method.ToString());
Real Codebase Usage
In real projects, developers usually choose one of these patterns.
1. Use ToString() when the enum name is the correct text
This is the simplest and most common approach.
string value = AuthenticationMethod.FORMS.ToString();
Good for:
- logging n- debugging
- internal messages
- simple display cases
2. Use an extension method for custom display text
This keeps enum-specific display logic in one place.
public static class AuthenticationMethodExtensions
{
public static string ToDisplayString(this AuthenticationMethod method)
{
return method switch
{
AuthenticationMethod.FORMS => "Forms",
AuthenticationMethod.WINDOWSAUTHENTICATION => "Windows",
AuthenticationMethod.SINGLESIGNON => "SSO",
_ => method.ToString()
};
}
}
Why teams like this:
- easy to read
- no reflection
- compile-time checking
- straightforward to debug
3. Use attributes when display metadata belongs on the enum itself
Attributes are useful when the enum carries metadata consumed in many places.
Examples:
- display names
- descriptions
- serialization labels
- UI text
Trade-offs:
- more setup
- usually requires reflection
- can be slower and more verbose than a switch-based method
4. Use guard clauses for invalid values
In production code, enums may contain unexpected values, especially after deserialization or casts.
public static string ToDisplayString(this AuthenticationMethod method)
{
return method switch
{
AuthenticationMethod.FORMS => "Forms",
AuthenticationMethod.WINDOWSAUTHENTICATION => "Windows",
AuthenticationMethod.SINGLESIGNON => "SSO",
_ => throw new ArgumentOutOfRangeException(nameof(method), method, "Unknown authentication method")
};
}
This helps catch bugs early.
5. Prefer explicit mapping over hidden magic
In many codebases, a simple switch or extension method is preferred over a reflection-heavy helper because it is easier for the next developer to understand immediately.
Common Mistakes
Mistake 1: Assuming an enum prints its numeric value by default
Many beginners expect this:
AuthenticationMethod method = AuthenticationMethod.FORMS;
Console.WriteLine(method); // expecting 1
But the output is:
FORMS
Why
Enums display their member names by default when converted to string.
Fix
Use a cast if you need the number:
Console.WriteLine((int)method); // 1
Mistake 2: Building custom attribute logic when ToString() already works
Broken by overengineering:
string value = StringEnum.GetStringValue(AuthenticationMethod.FORMS);
If you only want "FORMS", the simpler version is:
string value = AuthenticationMethod.FORMS.ToString();
Mistake 3: Using enum names as user-friendly labels
This works technically:
Console.WriteLine(AuthenticationMethod.WINDOWSAUTHENTICATION.ToString());
But it may produce awkward UI text:
WINDOWSAUTHENTICATION
Better
Map it to a cleaner display label:
"Windows"
Mistake 4: Forgetting invalid enum values are possible
This is legal:
AuthenticationMethod method = (AuthenticationMethod)99;
Console.WriteLine(method.ToString());
This may print:
99
Fix
Validate with Enum.IsDefined when needed:
if (Enum.IsDefined(typeof(AuthenticationMethod), method))
{
Console.WriteLine(method.ToString());
}
Mistake 5: Using reflection-based attributes for simple one-off mappings
Attributes are powerful, but for small enums they can make the code harder to follow.
If you only need a few custom labels, an extension method is often clearer.
Comparisons
| Approach | Best for | Pros | Cons |
|---|---|---|---|
ToString() | Getting the enum member name | Built-in, simple, no extra code | Cannot return custom labels |
Cast to int | Getting numeric value | Simple and fast | Not a string label |
switch / extension method | Small to medium custom mappings | Clear, explicit, fast, easy to debug | Must update code when enum changes |
| Custom attribute + reflection | Metadata attached to enum members | Keeps labels near enum definitions | More code, reflection overhead |
| Dictionary mapping | Runtime-configurable mappings | Flexible | Extra structure, can get out of sync |
ToString() vs custom attribute
AuthenticationMethod.FORMS.ToString(); // "FORMS"
Use this when the enum name itself is correct.
AuthenticationMethod.SINGLESIGNON.ToDisplayString(); // "SSO"
Use a mapping or attribute when the desired text differs from the enum name.
Extension method vs attribute
| Option | Good choice when | Example |
|---|---|---|
| Extension method | You want simple custom display logic | method.ToDisplayString() |
| Attribute | You want reusable metadata on the enum | [Description("SSO")] |
Cheat Sheet
// Enum definition
public enum AuthenticationMethod
{
FORMS = 1,
WINDOWSAUTHENTICATION = 2,
SINGLESIGNON = 3
}
Quick rules
- Use
enumValue.ToString()to get the enum member name. - Use
(int)enumValueto get the numeric value. - Use a custom mapping if the display text differs from the enum name.
Examples
AuthenticationMethod method = AuthenticationMethod.FORMS;
method.ToString(); // "FORMS"
(int)method; // 1
Simple custom display mapping
public static string ToDisplayString(AuthenticationMethod method)
{
return method switch
{
AuthenticationMethod.FORMS => "FORMS",
AuthenticationMethod.WINDOWSAUTHENTICATION => "WINDOWS",
AuthenticationMethod.SINGLESIGNON => "SSO",
_ => method.ToString()
};
}
Important edge case
AuthenticationMethod method = (AuthenticationMethod)99;
method.ToString(); // "99"
Invalid enum values can exist if you cast manually.
Best default choice
If you want the enum name exactly as declared:
AuthenticationMethod.FORMS.ToString()
FAQ
How do I get the string name of an enum in C#?
Use ToString():
AuthenticationMethod.FORMS.ToString(); // "FORMS"
Why does my enum sometimes show 1 instead of FORMS?
You are probably converting or casting it to an integer:
(int)AuthenticationMethod.FORMS // 1
ToString() returns the name, not the number.
Do I need a custom attribute to get enum text in C#?
Not if you only want the enum member name. Use ToString(). Attributes are useful only when you want custom text different from the enum name.
What is the best way to show friendly enum labels in a UI?
A small extension method or DescriptionAttribute is common. For a few values, an extension method with switch is usually the simplest.
Is ToString() enough for WINDOWSAUTHENTICATION to become WINDOWS?
No. ToString() returns "WINDOWSAUTHENTICATION". If you want "WINDOWS", you need custom mapping.
Should I use a dictionary or a switch for enum display strings?
For fixed enum values, a switch or extension method is usually clearer and easier to maintain. A dictionary is more useful when mappings are dynamic.
Can an enum contain invalid values in C#?
Yes. You can cast any integer to an enum type. That is why validation may be necessary in some cases.
Mini Project
Description
Build a small authentication display helper for a console app. The project demonstrates the difference between an enum's numeric value, its name, and a custom display string. This is useful in real applications where internal enum names do not always match the text shown to users or sent to external systems.
Goal
Create a console program that prints the enum name, numeric value, and friendly display text for each authentication method.
Requirements
- Define an
AuthenticationMethodenum with three values. - Print each enum value's name using
ToString(). - Print each enum value's numeric value by casting to
int. - Add a custom display method for user-friendly labels.
- Handle unexpected enum values safely.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
Best Way to Repeat a Character in C#: Building Repeated Strings Efficiently
Learn the best way to repeat a character in C#, compare StringBuilder, string concatenation, and simpler built-in options.
C# Access Modifiers and static: public, private, protected, and Defaults
Learn how C# public, private, protected, and default access control visibility, and how static differs from instance members.