C# – How to use enum flags to pass multiple options as a single parameter

When you need to pass multiple options into a method, normally you would add a bool flag for each parameter, like:

DoStuff(bool prettyPrint, bool useEnumStrings)

Not only is using bool flags a bit of a code smell, but when this list of parameters gets too big, you’ll probably want to refactor by moving the bool flags into an options class, like:

public class Options { public bool PrettyPrint {get;set;} public bool UseEnumStrings {get;set;} public bool IgnoreNulls {get;set;} } //caller new Options() { PrettyPrint=true, UseEnumStrings=true };

This is OK, but it’s pretty verbose. The caller has to new up an Options object and set all the flags it wants turned on.

There’s a simpler approach: enum flags.

With enum flags, you accept a single enum parameter, and the caller passes in all the options they want by bitwise ORing them together, like:

DoStuff(JsonOptions options) //caller DoStuff(PrettyPrint | JsonOptions.UseEnumStrings)

In this article I’ll show how to create and use enum flags.

1 – Create enum with Flags attribute

There are two things to know to set this up properly:

  • Add the [Flags] attribute to the enum.
  • Set the values to powers of 2.
[Flags] public enum JsonOptions { None = 0, PrettyPrint = 1, UseEnumStrings = 2, IgnoreNulls = 4, CaseInsensitive = 8 }

2 – Accept the enum as a parameter and check which options are set

I have the following class that builds JsonSerializerOptions objects to use with System.Text.Json. It accepts a single JsonOptions enum parameter and then creates the JsonSerializerOptions objects based on which options were passed in.

Use HasFlag() to check if an option is set.

public class JsonOptionsBuilder { private readonly JsonSerializerOptions NONE; public JsonOptionsBuilder() { NONE = new JsonSerializerOptions(); } public JsonSerializerOptions Build(JsonOptions jsonOptions) { if (jsonOptions == JsonOptions.None) { return NONE; } var jsonSerializerOptions = new JsonSerializerOptions() { IgnoreNullValues = jsonOptions.HasFlag(JsonOptions.IgnoreNulls), WriteIndented = jsonOptions.HasFlag(JsonOptions.PrettyPrint), PropertyNameCaseInsensitive = jsonOptions.HasFlag(JsonOptions.CaseInsensitive) }; if (jsonOptions.HasFlag(JsonOptions.UseEnumStrings)) { jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); } return jsonSerializerOptions; } }

3 – Pass in combos of the enum

To pass in combos of the enum, you need to bitwise OR them together (using the | operator).

In the following example, I am passing in options PrettyPrint and UseEnumStrings.

var people = new List<Person>() { new Person() { FirstName = "Daniel", LastName = "Jackson", Job = "Archaeologist", PetPreference= PetPreference.Dogs }, new Person() { FirstName = "Samantha", LastName = "Carter", Job = "Astrophysicist", PetPreference= PetPreference.Cats } }; var jsonOptionsBuilder = new JsonOptionsBuilder(); var options = jsonOptionsBuilder.Build(JsonOptions.PrettyPrint | JsonOptions.UseEnumStrings); var personJson = JsonSerializer.Serialize(people, options); Console.WriteLine(personJson);

Leave a Comment