How to Convert a String to an Enum and back in C#
Dec 17, 2025 • Chris Pietschmann • C#Enums are great for making code more readable and less error-prone than passing around “magic strings” or numbers. But in the real world, strings still happen — config files, query strings, JSON payloads, environment variables, user input, etc.
In this post, I’ll show a few practical ways to convert a string → enum, how to validate safely (without exceptions), and how to convert an enum → string in a couple different formats.
What is an enum?
An enum is a named set of constants. By default, the underlying type is int, and values start at 0 unless you specify otherwise.
public enum WeekDays
{
Sunday = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6
}
Convert a string to an enum
1) Enum.Parse (simple, but throws on bad input)
If you already know the input is valid (or you’re fine with exceptions), Enum.Parse is the most direct option.
string dayName = "Friday";
WeekDays day = (WeekDays)Enum.Parse(typeof(WeekDays), dayName);
Console.WriteLine(day); // Friday
Case sensitivity: by default, Enum.Parse is case-sensitive.
string dayName = "friday";
// Throws ArgumentException (case-sensitive by default)
WeekDays day = (WeekDays)Enum.Parse(typeof(WeekDays), dayName);
To ignore case:
string dayName = "friday";
WeekDays day = (WeekDays)Enum.Parse(typeof(WeekDays), dayName, ignoreCase: true);
Console.WriteLine(day); // Friday
2) Enum.TryParse (recommended, no exceptions)
For anything involving external input, Enum.TryParse is usually the better choice.
string dayName = "Friday";
if (Enum.TryParse(dayName, out WeekDays day))
{
Console.WriteLine(day); // Friday
}
else
{
Console.WriteLine("Invalid day name!");
}
If you want case-insensitive parsing:
string dayName = "friday";
if (Enum.TryParse(dayName, ignoreCase: true, out WeekDays day))
{
Console.WriteLine(day); // Friday
}
A subtle gotcha: numeric strings also parse
One “surprise” is that Enum.TryParse (and Enum.Parse) can accept numeric strings too.
string input = "4";
if (Enum.TryParse(input, out WeekDays day))
{
Console.WriteLine(day); // Thursday (because Thursday = 4)
}
And if the numeric value is not defined, parsing can still succeed — you’ll get an enum value that has no named member:
string input = "10";
if (Enum.TryParse(input, out WeekDays day))
{
Console.WriteLine(day); // 10
}
So if you need to enforce “must be one of the defined enum values”, you’ll want validation.
Validate that the parsed value is actually defined
Using Enum.IsDefined (works well for non-Flags enums)
string input = "10";
if (Enum.TryParse(input, out WeekDays day) && Enum.IsDefined(typeof(WeekDays), day))
{
Console.WriteLine(day);
}
else
{
Console.WriteLine("Not a defined WeekDays value.");
}
This is a good way to prevent “random numbers in an enum suit”.
Convert an enum back to a string
1) ToString() (the common case)
WeekDays day = WeekDays.Friday;
string text = day.ToString();
Console.WriteLine(text); // Friday
If the enum value doesn’t have a named member (like 10), ToString() returns the numeric text:
WeekDays day = (WeekDays)10;
Console.WriteLine(day.ToString()); // 10
2) Format strings: "G", "D", "X", and "F"
The Enum.ToString(string format) overload gives you a few useful options.
WeekDays day = WeekDays.Friday;
Console.WriteLine(day.ToString("G")); // Friday (General)
Console.WriteLine(day.ToString("D")); // 5 (Decimal)
Console.WriteLine(day.ToString("X")); // 00000005 (Hex)
Working with [Flags] enums
Flags enums represent combinations of values and are typically parsed from comma-separated strings.
[Flags]
public enum FilePermissions
{
None = 0,
Read = 1,
Write = 2,
Execute = 4
}
Parse a flags string
string input = "Read, Write";
if (Enum.TryParse(input, ignoreCase: true, out FilePermissions perms))
{
Console.WriteLine(perms); // Read, Write
}
Convert flags to string
FilePermissions perms = FilePermissions.Read | FilePermissions.Write;
Console.WriteLine(perms.ToString("G")); // Read, Write
Console.WriteLine(perms.ToString("D")); // 3
Console.WriteLine(perms.ToString("F")); // Read, Write
Note:
Enum.IsDefinedis usually not the right validator for flags combinations, because a combination (likeRead | Write) may be valid even if you never defined a named member with value3.
Validate a flags value using a bitmask
A common approach is: ensure no bits are set outside the allowed flags.
static bool IsValidFlags<TEnum>(TEnum value) where TEnum : struct, Enum
{
ulong raw = Convert.ToUInt64(value);
// Build a mask of all defined values in the enum.
ulong mask = 0;
foreach (var v in Enum.GetValues<TEnum>())
{
mask |= Convert.ToUInt64(v);
}
// If value contains bits not present in the mask, it's invalid.
return (raw & ~mask) == 0;
}
Usage:
string input = "Read, Write";
if (Enum.TryParse(input, ignoreCase: true, out FilePermissions perms) && IsValidFlags(perms))
{
Console.WriteLine(perms); // Read, Write
}
else
{
Console.WriteLine("Invalid permissions value.");
}
Generic helper methods
If you do this a lot, wrapping it up can keep your code tidy.
Safe parse (returns bool)
public static bool TryToEnum<TEnum>(string? input, out TEnum value, bool ignoreCase = true)
where TEnum : struct, Enum
{
value = default;
if (string.IsNullOrWhiteSpace(input))
return false;
if (!Enum.TryParse(input, ignoreCase, out value))
return false;
// Prevent "10" from becoming a non-defined enum value (for non-Flags enums).
if (!typeof(TEnum).IsDefined(typeof(FlagsAttribute), inherit: false))
return Enum.IsDefined(typeof(TEnum), value);
// For Flags enums, allow combinations but reject unknown bits.
return IsValidFlags(value);
}
Parse-or-default (handy for config)
public static TEnum ToEnumOrDefault<TEnum>(string? input, TEnum defaultValue, bool ignoreCase = true)
where TEnum : struct, Enum
{
return TryToEnum<TEnum>(input, out var value, ignoreCase) ? value : defaultValue;
}
Wrap-up
- Use
Enum.TryParsefor anything that might be invalid input. - Remember: numeric strings can parse successfully, even if the value isn’t defined.
- Validate with
Enum.IsDefinedfor non-flags enums. - For
[Flags], validate using a bitmask so legitimate combinations still pass. - Use
ToString()(or format strings like"D"/"X") to convert back to a string.
That’s it — string ↔ enum conversions without surprises.
Chris Pietschmann
Cloud Infra & Security | Microsoft MVP | HashiCorp Ambassador | MCT | Developer | Author
I am a solution architect, SRE, developer, trainer and author. With 25 years of experience in the Software Development industry that includes working as a Consultant and Trainer in a wide array of different industries.




