C# String to Enum: Parsing and Validation
c# string to enum: Learn how to convert strings to enum values in C# using Enum.Parse and Enum.TryParse, including case handling, validation, and performance considera...
c# string to enum requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.
Converting a string to an enum in C# is a common operation when working with configuration files, API inputs, or user input. The Enum class provides two main methods for this: Enum.Parse and Enum.TryParse. Choosing the right one depends on whether you expect the input to always be valid and how you want to handle failures.
Using Enum.Parse for Direct Conversion
The simplest way to convert a string to an enum is Enum.Parse. It takes the enum type and the string value, and returns the enum value.
public enum Color { Red, Green, Blue } string input = "Green"; Color color = (Color)Enum.Parse(typeof(Color), input);
Enum.Parse is static and returns an object, so you need to cast it to your enum type. If the string does not match any defined enum member, it throws an ArgumentException. This makes it suitable for scenarios where the input is known to be valid, but it can be brittle if the input comes from an external source.
Using Enum.TryParse for Safe Conversion
When the input may be invalid, Enum.TryParse is the safer choice. It returns a boolean indicating success and outputs the parsed value.
if (Enum.TryParse(input, out Color color)) { Console.WriteLine($"Parsed: {color}"); } else { Console.WriteLine("Invalid color name."); }
Enum.TryParse does not throw an exception on failure, which avoids the overhead of exception handling and keeps the control flow straightforward. It also works with the generic type parameter, so you don't need a cast.
Handling Case Sensitivity and Whitespace
By default, both Enum.Parse and Enum.TryParse are case-sensitive. If you need to accept input like "green" or " GREEN ", you can pass true for the ignoreCase parameter.
Color color = (Color)Enum.Parse(typeof(Color), input, ignoreCase: true);
Similarly, Enum.TryParse has an overload that accepts ignoreCase:
if (Enum.TryParse(input, ignoreCase: true, out Color color)) { // ... }
Neither method trims whitespace automatically. If your input may contain leading or trailing spaces, call Trim() before parsing to avoid unexpected failures.
Validating That the Parsed Value Is Defined
Enum.Parse and Enum.TryParse will parse any numeric string that fits the underlying type, even if it does not correspond to a named enum member. For example, if your enum has values 0, 1, and 2, the string "5" will parse successfully to the numeric value 5, even though no member is named 5. This can lead to invalid states in your application.
To ensure the parsed value is actually defined, use Enum.IsDefined after parsing:
if (Enum.TryParse(input, out Color color) && Enum.IsDefined(typeof(Color), color)) { // Valid enum value }
This check is especially important when the enum is used as a flag or when you need to guarantee that only known values are processed.
Performance Considerations
Enum.TryParse is generally more efficient than Enum.Parse when the input might be invalid, because it avoids throwing and catching exceptions. Exception handling is expensive, especially in high-throughput scenarios. If you are parsing many strings in a loop, prefer TryParse with a pre-validated set of inputs.
The ignoreCase option adds a small overhead because it performs case-insensitive comparison. If you know the input format is consistent, keep the default case-sensitive behavior to reduce work.
For extremely hot paths, consider caching the parsed values in a Dictionary<string, TEnum> if the set of strings is limited. This avoids repeated parsing logic entirely.
Common Pitfalls and Edge Cases
One common mistake is assuming that Enum.Parse handles numeric strings correctly. It does, but as mentioned, it may produce values not defined in the enum. Another pitfall is forgetting that enum names can be duplicated if you use aliases. Enum.Parse returns the first match, which may not be the one you expect.
Also, note that Enum.TryParse is case-sensitive by default, so "red" will fail unless you pass true for ignoreCase. If you are parsing user input, always decide on a consistent casing policy.
Choosing the Right Approach for Your Scenario
The decision between Enum.Parse and Enum.TryParse comes down to how you handle errors. Use Enum.Parse when you are certain the input is valid and you want an exception to propagate if it is not. Use Enum.TryParse when the input is untrusted or optional, and you want to handle failure gracefully.
If you need to ensure the parsed value is a defined member, combine TryParse with Enum.IsDefined. For performance-sensitive code, avoid exceptions and consider a lookup dictionary for a fixed set of strings.