You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -9,9 +16,25 @@ In general, we recommend installing the [NetEscapades.EnumGenerators](https://ww
9
16
10
17
> [NetEscapades.EnumGenerators](https://www.nuget.org/packages/NetEscapades.EnumGenerators) requires the .NET 7 SDK or higher. [NetEscapades.EnumGenerators.Interceptors](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Interceptors) requires the .NET 8.0.400 SDK or higher. You can still target earlier frameworks like .NET Core 3.1 etc, the version requirement only applies to the version of the .NET SDK installed.
11
18
19
+
<!-- toc -->
20
+
## Contents
21
+
22
+
*[Why use these packages?](#why-use-these-packages)
23
+
*[Adding NetEscapades.EnumGenerators.Generators to your project](#adding-netescapadesenumgeneratorsgenerators-to-your-project)
*[Preserving usages of the `[EnumExtensions]` attribute](#preserving-usages-of-the-enumextensions-attribute)<!-- endToc -->
34
+
12
35
## Why use these packages?
13
36
14
-
Many methods that work with enums are surprisingly slow. Calling `ToString()` or `HasFlag()` on an enum seems like it _should_ be fast, but it often isn't. This package provides a set of extension methods, such as `ToStringFast()` or `HasFlagFast()` that are designed to be very fast, with fewer allocations.
37
+
Many methods that work with enums are surprisingly slow. Calling `ToString()` or `HasFlag()` on an enum seems like it _should_ be fast, but it often isn't. This package provides a set of extension methods, such as `ToStringFast()` or `HasFlagFast()` that are designed to be very fast, with fewer allocations.<!-- include: benchmark. path: /fragments/benchmark.include.md -->
15
38
16
39
17
40
For example, the following benchmark shows the advantage of calling `ToStringFast()` over `ToString()`:
@@ -44,25 +67,7 @@ public enum Color
44
67
Blue=1,
45
68
}
46
69
```
47
-
48
-
The main downside to the extension methods generated by [NetEscapades.EnumGenerators](https://www.nuget.org/packages/NetEscapades.EnumGenerators) is that you have to remember to use them. The [NetEscapades.EnumGenerators.Interceptors](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Interceptors) package solves this problem by intercepting calls to `ToString()` and replacing them with calls `ToStringFast()` automatically using the .NET compiler feature called [interceptors](https://github.com/dotnet/roslyn/blob/main/docs/features/interceptors.md).
49
-
50
-
51
-
For example, imagine you have this code, which uses the `Color` enum defined above:
By default you need to manually replace these `ToString()` calls with `ToStringFast()`. However, when you use the [NetEscapades.EnumGenerators.Interceptors](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Interceptors), the interceptor automatically replaces the call to `choice.ToString()` at compile-time with a call to `ToStringFast()`, as though you wrote the following:
There are many caveats to this behaviour, as described below, but any explicit calls to `ToString()` or `HasFlag()` on a supported enum are replaced automatically.
70
+
<!-- endInclude -->
66
71
67
72
## Adding NetEscapades.EnumGenerators.Generators to your project
68
73
@@ -85,14 +90,14 @@ This adds a `<PackageReference>` to your project. You can additionally mark the
Adding the package will automatically add a marker attribute, `[EnumExtensions]`, to your project.
100
+
Adding the package will automatically add a marker attribute, `[EnumExtensions]`, to your project.<!-- include: enum-usage. path: /fragments/enum-usage.include.md -->
96
101
97
102
To use the generator, add the `[EnumExtensions]` attribute to an enum. For example:
98
103
@@ -102,7 +107,7 @@ public enum MyEnum
102
107
{
103
108
First,
104
109
105
-
[Display(Name="2nd")]
110
+
[EnumMember(Value="2nd")]
106
111
Second,
107
112
}
108
113
```
@@ -160,7 +165,7 @@ public static partial class MyEnumExtensions
160
165
returntrue;
161
166
}
162
167
163
-
168
+
164
169
returnnameswitch
165
170
{
166
171
nameof(MyEnum.First) =>true,
@@ -181,7 +186,7 @@ public static partial class MyEnumExtensions
_NetEscapades.EnumGenerators_ includes optional analyzers that encourage the use of the generated extension methods instead of the built-in `System.Enum` methods. These analyzers can help improve performance by suggesting the faster, generated, alternatives like `ToStringFast()`, `HasFlagFast()`, and `TryParse()`.
@@ -363,7 +371,7 @@ After using one of these configuration options, the analyzers in your project sh
363
371
364
372
### Configuring analyzer severity (optional)
365
373
366
-
Once enabled, you can optionally configure the severity of individual analyzer rules using one or more [`.editorconfig` files](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/configuration-files#editorconfig). For example, the following changes all the built-in analyzers to report usages as errors instead of warnings
374
+
Once enabled, you can optionally configure the severity of individual analyzer rules using one or more [`.editorconfig` files](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/configuration-files#editorconfig). For example, the following changes all the built-in analyzers to report usages as errors instead of warnings
All usage analyzers include automatic code fixes. When a diagnostic is triggered, you can use the quick fix functionality in your IDE to automatically replace the `System.Enum` method with the corresponding generated extension method:
408
416
409
-

417
+
<!-- endInclude -->
[NetEscapades.EnumGenerators](https://www.nuget.org/packages/NetEscapades.EnumGenerators) is a metapackage that references additional packages for functionality.
/// Options to apply when calling <c>ToStringFast</c> on an enum.
472
+
/// Options to apply when calling <c>ToStringFast</c> on an enum.
464
473
/// </summary>
465
474
publicreadonlystructSerializationOptions
466
475
467
476
/// <summary>
468
-
/// Transform to apply when calling <c>ToStringFast</c>
477
+
/// Transform to apply when calling <c>ToStringFast</c>
469
478
/// </summary>
470
479
public enum SerializationTransform
471
480
```
@@ -479,7 +488,7 @@ namespace SomeNameSpace;
479
488
publicstaticpartialclass MyEnumExtensions
480
489
{
481
490
// ... generated members
482
-
491
+
483
492
// The runtime dependencies are generated as nested types instead
484
493
publicreadonlystructEnumParseOptions { }
485
494
publicreadonlystructSerializationOptions
@@ -538,9 +547,28 @@ The final option is to reference [NetEscapades.EnumGenerators.Generators](https:
538
547
```
539
548
540
549
> [!WARNING]
541
-
>Whenusingthe [NetEscapades.EnumGenerators](https://www.nuget.org/packages/NetEscapades.EnumGenerators) metapackage, it's important you _don't_ set `PrivateAssets=All`. If you want to use `PrivateAssets=All`, use [NetEscapades.EnumGenerators.Generators](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Generators) for this scenario.
550
+
>Whenusingthe [NetEscapades.EnumGenerators](https://www.nuget.org/packages/NetEscapades.EnumGenerators) metapackage, it's important you _don't_ set `PrivateAssets=All`. If you want to use `PrivateAssets=All`, use [NetEscapades.EnumGenerators.Generators](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Generators) for this scenario.<!-- endInclude -->
551
+
552
+
## Enabling automatic interception (experimental)
553
+
554
+
Themaindownsidetotheextensionmethodsgeneratedby [NetEscapades.EnumGenerators](https://www.nuget.org/packages/NetEscapades.EnumGenerators) is that you have to remember to use them. The [NetEscapades.EnumGenerators.Interceptors](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Interceptors) package solves this problem by intercepting calls to `ToString()` and replacing them with calls `ToStringFast()` automatically using the .NET compiler feature called [interceptors](https://github.com/dotnet/roslyn/blob/main/docs/features/interceptors.md).<!-- include: interceptor-intro. path: /fragments/interceptor-intro.include.md -->
Bydefaultyouneedtomanuallyreplacethese `ToString()` callswith `ToStringFast()`. However, whenyouusethe [NetEscapades.EnumGenerators.Interceptors](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Interceptors), the interceptor automatically replaces the call to `choice.ToString()` at compile-time with a call to `ToStringFast()`, as though you wrote the following:
Thisaddsa `<PackageReference>` toyourproject. Youcanadditionallymarkthepackageas `PrivateAssets="all"` and `ExcludeAssets="runtime"`, similarlyto_NetEscapades.EnumGenerators_.
556
584
557
-
Bydefault, adding [NetEscapades.EnumGenerators.Interceptors](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Interceptors) to a project enables interception for all enums _defined in that project_ that use the `[EnumExtensions]` or `[EnumExtensions<T>]` attributes. If you wish to intercept calls made to enums with extensions defined in _other_ projects, you must add the `[Interceptable<T>]` attribute in the project where you want the interception to happen, e.g.
585
+
Bydefault, adding [NetEscapades.EnumGenerators.Interceptors](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Interceptors) to a project enables interception for all enums _defined in that project_ that use the `[EnumExtensions]` or `[EnumExtensions<T>]` attributes. If you wish to intercept calls made to enums with extensions defined in _other_ projects, you must add the `[Interceptable<T>]` attribute in the project where you want the interception to happen, e.g.<!-- include: interception-config. path: /fragments/interception-config.include.md -->
558
586
559
587
```csharp
560
588
[assembly:Interceptable<DateTimeKind>]
@@ -598,7 +626,7 @@ public void CantIntercept()
598
626
{
599
627
varbad1= ((System.Enum)Color.Red).ToString(); // ❌ Base type
600
628
varbad2= ((object)Color.Red).ToString(); // ❌ Base type
## Preserving usages of the `[EnumExtensions]` attribute
614
644
615
645
The `[EnumExtensions]` attributeisdecoratedwiththe `[Conditional]` attribute, [sotheirusagewillnotappearinthebuildoutputofyourproject](https://andrewlock.net/conditional-compilation-for-ignoring-method-calls-with-the-conditionalattribute/#applying-the-conditional-attribute-to-classes). If you use reflection at runtime on one of your `enum`s, you will not find `[EnumExtensions]` in the list of custom attributes. If you wish to preserve these attributes in the build output, you can define the `NETESCAPADES_ENUMGENERATORS_USAGES` MSBuild variable.
@@ -628,3 +658,4 @@ The `[EnumExtensions]` attribute is decorated with the `[Conditional]` attribute
[NetEscapades.EnumGenerators.Generators](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Generators) is a source generator package that generates extension methods for enums, to allow fast "reflection".
7
+
8
+
In general, we recommend installing the [NetEscapades.EnumGenerators](https://www.nuget.org/packages/NetEscapades.EnumGenerators) metapackage. [See below](#package-referencing-options) for details on choosing between these two packages.
9
+
10
+
> [NetEscapades.EnumGenerators](https://www.nuget.org/packages/NetEscapades.EnumGenerators) requires the .NET 7 SDK or higher. [NetEscapades.EnumGenerators.Interceptors](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Interceptors) requires the .NET 8.0.400 SDK or higher. You can still target earlier frameworks like .NET Core 3.1 etc, the version requirement only applies to the version of the .NET SDK installed.
11
+
12
+
toc
13
+
14
+
## Why use these packages?
15
+
16
+
include: benchmark
17
+
18
+
## Adding NetEscapades.EnumGenerators.Generators to your project
This adds a `<PackageReference>` to your project. You can additionally mark the package as `PrivateAssets="all"` and `ExcludeAssets="runtime"`.
27
+
28
+
> Setting `PrivateAssets="all"` means any projects referencing this one won't get a reference to the _NetEscapades.EnumGenerators.Generators_ package. Setting `ExcludeAssets="runtime"` ensures the _NetEscapades.EnumGenerators.Attributes.dll_ file is not copied to your build output (it is not required at runtime).
Interceptors were introduced as an experimental feature in C#12 with .NET 8. They allow a source generator to "intercept" certain method calls, and replace the call with a different one. _NetEscapades.EnumGenerators_ has support for intercepting `ToString()` and `HasFlag()` method calls.
57
+
58
+
> To use interceptors, you must be using at least version 8.0.400 of the .NET SDK. [This ships with Visual Studio version 17.11](https://learn.microsoft.com/en-us/dotnet/core/porting/versioning-sdk-msbuild-vs), so you will need at least that version or higher.
59
+
60
+
To use interception, add the additional NuGet package [NetEscapades.EnumGenerators.Interceptors](https://www.nuget.org/packages/NetEscapades.EnumGenerators.Interceptors) to your project using:
This adds a `<PackageReference>` to your project. You can additionally mark the package as `PrivateAssets="all"` and `ExcludeAssets="runtime"`, similarly to _NetEscapades.EnumGenerators_.
0 commit comments