SkillAgentSearch skills...

FastEnum

A source generator to generate common methods for your enum types at compile-time.

Install / Use

/learn @Genbox/FastEnum
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

FastEnum

NuGet License

Description

A source generator to generate common methods for your enum types at compile-time. Print values, parse, or get the underlying value of enums without using reflection.

Features

  • Intuitive API with discoverability through IntelliSense. All enums can be accessed via the Enums class.
  • High-performance
    • Zero allocations whenever possible.
    • GetMemberNames(), GetMemberValues() etc. are cached by default. Use DisableCache to disable it.
    • MemberCount and IsFlagsEnum is const to allow the compiler to fold constants.
  • Supports name and description from DisplayAttribute.
  • Support for flag enums via the FlagsAttribute.
  • Support for skipping enum values completely with [EnumOmitValue] on enum members.
  • Support for private/internal enums
  • Support for enums nested inside classes
  • Support for user-set underlying values such as long, uint, byte, etc.
  • Support for duplicate enum names from different namespaces
  • Support for enums that reside in the global namespace
  • Has several options to control namespace, class name and more for generated code. See Options section below for details.

Examples

Lets create a very simple enum, and add the [FastEnum] attribute to it.

[FastEnum]
public enum Color
{
    Red,
    Green,
    Blue
}

Extensions

Extensions tell you something about an instance of an enum you have. For example, MyEnum.Value1.GetString() is the same as MyEnum.Value1.ToString() from dotnet, except that it does not need to do any work at runtime.

The following extensions are auto-generated:

Color c = Color.Red;

Console.WriteLine("String value: " + e.GetString());
Console.WriteLine("Underlying value: " + e.GetUnderlyingValue());

Output:

String value: Red
Underlying value: 0

Enums class

Enums is a class that contains metadata about the auto-generated enum.

Console.WriteLine("Number of members: " + Enums.Color.MemberCount);
Console.WriteLine("Parse: " + Enums.Color.Parse("Red"));
Console.WriteLine("Is Green part of the enum: " + Enums.Color.IsDefined(Color.Green));

PrintArray("Member names:", Enums.Color.GetMemberNames());
PrintArray("Underlying values:", Enums.Color.GetUnderlyingValues());

PrintArray simply iterates an array and list the values on separate lines.

Output:

Number of members: 3
Parse: Red
Is Green part of the enum: True
Member names:
- Red
- Green
- Blue
Underlying values:
- 0
- 1
- 2

Values via attributes

DisplayAttribute

If you add DisplayAttribute to an enum, the source generator will generate extra methods. For example, you can add [DisplayAttribute] to an enum value like this:

[FastEnum]
internal enum MyEnum
{
    [Display(Name = "Value1Name", Description = "Value1Description")]
    Value1 = 1,
    Value2 = 2
}

It will generate GetDisplayName() and GetDescription() extensions to your enum.

MyEnum e = MyEnum.Value1;
Console.WriteLine("Display name: " + e.GetDisplayName());
Console.WriteLine("Description: " + e.GetDescription());

Prefer the TryGetDisplayName(), TryGetDescription() and TryGetUnderlyingValue() helpers when you want a boolean + out pattern instead of exceptions.

Output:

Display name: Value1Name
Description: Value1Description

FlagsAttribute

If you have an enum with the FlagsAttribute, FastEnum will add a method called IsFlagSet().

[Flags]
[FastEnum]
internal enum MyFlagsEnum
{
    None = 0,
    Value1 = 1,
    Value2 = 2
    Value3 = 4
}
MyFlagsEnum e = MyFlagsEnum.Value1 | MyFlagsEnum.Value3;
Console.WriteLine("Is Value2 set: " + e.IsFlagSet(MyFlagsEnum.Value2));

Output:

Is Value2 set: False

Options

[FastEnum] have several options to control the behavior of the generated code.

ExtensionClassName

The generated extension class is partial by default. So if you want to combine extension from your own class and the autogenerated one, you can use this option to set the name to the same as your extensions class. Defaults to <EnumName>Extensions.

ExtensionClassNamespace

Use this to control which namespace the extensions class belongs to. Defaults to the namespace of the enum.

ExtensionClassVisibility

Use this to override the visibility of the generated extensions class. Defaults to the enum's own visibility (Visibility.Inherit).

[FastEnum(ExtensionClassVisibility = Visibility.Internal)] // Generates an internal StatusExtensions class instead of public.
public enum Status { Ok, Error }

EnumsClassName

Use this to set the name of the Enums class to something else.

EnumsClassNamespace

Used this to specify the namespace for the Enums class. Defaults to the namespace of the enum.

EnumsClassVisibility

Use this to override the visibility of the generated Enums wrapper class. Defaults to the enum's own visibility (Visibility.Inherit).

[FastEnum(EnumsClassVisibility = Visibility.Internal)] // Enums.Status will be internal.
public enum Status { Ok, Error }

EnumNameOverride

Sometimes you might have two enums named the same, but in different namespaces. You can use this option to override the name of the enum in the generated code. For example, if your enum is named MyEnum the Enums class can be accessed like this:

Enums.MyEnum.GetMemberNames()

If you set EnumNameOverride to OtherEnum it will look like this instead:

Enums.OtherEnum.GetMemberNames()

DisableEnumsWrapper

Enable this to avoid generating the static Enums class that wraps all the enums. When enabled, Enums.MyEnum becomes MyEnum. This is handy if you want to set all enums inside the same namespace across projects. Note that you must use EnumNameOverride or set EnumsClassNamespace to something to avoid the name collision between your enum and the generated class.

DisableCache

By default arrays from GetMemberNames(), GetMemberValues() etc. is cached to avoid an allocation each time you call them. If your application only needs the arrays once, then caching them in memory take up unnecessary space. Use this option to disable the cache.

Transformations

You can transform the string output of enums with [EnumTransform] at compile time. There are a few ways to do this.

[EnumTransform(Preset = EnumTransform.UpperCase)] //Will uppercase all enum values
[EnumTransform(Regex = "/^Enum//")] //A regex to replace values starting with "Enum" with nothing.
[EnumTransform(CasePattern = "U_U_U")] //Uppercase the first, third and fifth characters

Note: You can only specify one [EnumTransform] at the time.

Regex must have the format /regex-here/replacement-here/.

CasePattern is a way to either uppercase, lowercase or omit charaters.

The language uses the following modifier chars:

  • U: Uppercase the char
  • L: Lowercase the char
  • O: Omit the char
  • _: Do nothing. Keep the char as-is.

Let's say you want to omit the first character in all values, uppercase the third character and lowercase the rest.

[FastEnum]
[EnumTransform(CasePattern = "OOULLLLL")]
public enum MyEnum
{
    Myvalue1,
    Myvalue2,
    Myvalue3
}

The pattern is matched as much as possible. A pattern of U will simply uppercase the first character, and a pattern of UUUUUUUUUUUU will uppercase the first 12 characters, even if the enum value is only 6 characters long.

[EnumTransform] options:

  • Preset uppercases or lowercases all member names.
  • Regex allows replacing a pattern.
  • CasePattern applies a simple U/L/O/_ mask.
  • SortMemberNames, SortMemberValues, SortUnderlyingValues, SortDisplayNames, SortDescriptions control ordering of the corresponding generated arrays. Defaults to EnumOrder.None; set to Ascending or Descending to change.
[FastEnum]
[EnumTransform(Preset = EnumTransform.UpperCase)]
public enum Color { Red, Green }
// GetString(Color.Red) => "RED"

[FastEnum]
[EnumTransform(Regex = "/^Clr//")]
public enum Color { ClrRed, ClrGreen }
// GetString(Color.ClrRed) => "Red"

[FastEnum]
[EnumTransform(CasePattern = "UOlll")]
public enum Color { apple, pears }
// GetString(Color.apple) => "Apple"
// GetString(Color.pears) => "Pears"

[FastEnum]
[EnumTransform(SortMemberNames = EnumOrder.Descending)]
public enum Nato { Alpha, Bravo, Charlie }
// GetMemberNames() => ["Charlie", "Bravo", "Alpha"]

You can override the string for specific members with [EnumTransformValue(ValueOverride = "...")]. This is useful when most values follow a pattern but a few need custom text.

[EnumTransformValue] options:

  • ValueOverride changes the generated string for that member and what TryParse will accept for it.
[FastEnum]
public enum Status
{
    [EnumTransformValue(ValueOverride = "all good")]
    Ok,
    Error
}
// GetString(Status.Ok) => "all good"
// Enums.Status.TryParse("all good", out var s) => true

[EnumTransform] also accepts ordering hints so generated lists come out sorted without extra runtime work:

  • SortMemberNames, SortMemberValues, SortUnderlyingValues affect the ordering of GetMemberNames(), GetMemberValues() and GetUnderlyingValues().
  • SortDisplayNames, SortDescriptions affect the or

Related Skills

View on GitHub
GitHub Stars11
CategoryDevelopment
Updated3mo ago
Forks1

Languages

C#

Security Score

92/100

Audited on Dec 6, 2025

No findings