Back to Blog
C#

C# Enum Parse: Converting Strings to Enum Values

c# enum parse: Learn how to parse strings into C# enum values safely, handle invalid input, and manage case sensitivity and flags enums.

enumparsingC#.NETstring conversionEnum.TryParse
Illustration of converting a text string into an enum value in C# with a gear and code symbol.

c# enum parse requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

When you receive input from a configuration file, a JSON payload, or a query parameter, you often need to convert a string into an enum value. In C#, the Enum.Parse and Enum.TryParse methods are the standard tools for this conversion. This article covers how to use them correctly, what happens when input is invalid, and how to handle case sensitivity, numeric strings, and flags enums.

Parsing a String with Enum.Parse

The Enum.Parse method converts a string representation of an enum member into the corresponding enum value. The simplest overload takes the enum type and the string to parse:

enum Color { Red, Green, Blue } Color color = (Color)Enum.Parse(typeof(Color), "Green"); Console.WriteLine(color); // Output: Green

The method returns an object, so you must cast it to the target enum type. If the string does not match any defined member, Enum.Parse throws an ArgumentException. That makes it unsuitable for untrusted input unless you wrap it in a try-catch block.

Handling Invalid Input with Enum.TryParse

For safer parsing, Enum.TryParse<T> returns a boolean instead of throwing an exception. It also outputs the parsed value through an out parameter:

if (Enum.TryParse<Color>("Red", out Color color)) { Console.WriteLine(color); } else { Console.WriteLine("Invalid color name"); }

TryParse is generic, so you don't need a cast. It also accepts the enum type as a non-generic overload, but the generic version is more readable and avoids casting. When the input is invalid, TryParse returns false and sets out to the default value of the enum (usually zero). This pattern is ideal for user input, API parameters, or any data that might be malformed.

Case Sensitivity and the ignoreCase Parameter

Both Enum.Parse and Enum.TryParse are case-sensitive by default. That means "red" will not match Color.Red. To allow case-insensitive matching, use the overload that takes an ignoreCase boolean:

Enum.TryParse<Color>("red", ignoreCase: true, out Color color);

The ignoreCase parameter is available in both methods. For Enum.Parse, the overload is Enum.Parse(Type enumType, string value, bool ignoreCase). When you set it to true, the parser compares member names using the current culture's case rules. Be aware that case-insensitive matching is slightly slower because it involves more complex comparison logic, but the difference is negligible for typical usage.

Parsing Numeric Strings and Underlying Values

Enums have an underlying numeric type, usually int. The parsing methods also accept numeric strings. For example, "1" will parse to Color.Green if Green is defined as 1. This behavior can be convenient, but it also introduces a risk: a string that looks like a number will be accepted even if it doesn't correspond to a named member. For instance, "99" would parse successfully to a Color value of 99, even though no member has that value. This is allowed because enums are not restricted to defined members at runtime.

If you need to ensure that the parsed value is one of the defined named constants, you must verify it with Enum.IsDefined:

if (Enum.TryParse<Color>("99", out Color color) && Enum.IsDefined(typeof(Color), color)) { // Only accept named values }

This check is important when the enum represents a fixed set of options and you don't want arbitrary numeric values to slip through.

Parsing Flags Enums and Comma-Separated Values

Flags enums, which use the [Flags] attribute, can represent combinations of values. The parsing methods support comma-separated lists of names. For example:

[Flags] enum Permissions { None = 0, Read = 1, Write = 2, Execute = 4 } Enum.TryParse<Permissions>("Read, Write", out Permissions perms);

The parser splits the string on commas and combines the corresponding values with a bitwise OR. It also handles numeric strings in the same way. However, if any part of the comma-separated string is invalid, the entire parse fails and returns false. This behavior is consistent, but it means you can't partially parse a list.

When working with flags, be careful with the None value. If the string is "None", it parses to zero, which is fine. But if you parse an empty string, TryParse returns false because an empty string is not a valid enum representation.

Performance Considerations for Repeated Parsing

Enum.Parse and Enum.TryParse are relatively fast, but they do involve reflection and string comparison. If you are parsing the same set of strings repeatedly in a hot path, you can cache the results in a Dictionary<string, YourEnum>. This avoids the overhead of parsing on every call. For example:

private static readonly Dictionary<string, Color> ColorMap = new Dictionary<string, Color>(StringComparer.OrdinalIgnoreCase) { ["Red"] = Color.Red, ["Green"] = Color.Green, ["Blue"] = Color.Blue };

Then you can use ColorMap.TryGetValue(input, out var color) instead of calling Enum.TryParse. This approach also gives you full control over case sensitivity and allows you to reject numeric strings if that's a requirement. The tradeoff is that you must maintain the dictionary manually, so it's only worthwhile when parsing happens frequently and the enum's members are stable.

Choosing Between Enum.Parse and Enum.TryParse

The decision between the two methods comes down to how you want to handle invalid input. Use Enum.Parse when you are certain the input is valid, such as when it comes from a controlled source and you want an exception to surface a programming error. Use Enum.TryParse when the input is external, like user input, configuration values, or API parameters, and you need to handle failures gracefully. In most production code, Enum.TryParse is the safer choice because it avoids exception overhead and makes the control flow explicit.

Also consider the Enum.IsDefined check when you need to restrict values to named members. The parsing methods themselves do not enforce that restriction, and relying on that behavior can lead to subtle bugs when an enum's underlying values change.

c# enum parse: Practical Usage and Code Examples | RYUSLOG DEV