EnumVisitorGenerator 1.1.2

dotnet add package EnumVisitorGenerator --version 1.1.2
                    
NuGet\Install-Package EnumVisitorGenerator -Version 1.1.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EnumVisitorGenerator" Version="1.1.2">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EnumVisitorGenerator" Version="1.1.2" />
                    
Directory.Packages.props
<PackageReference Include="EnumVisitorGenerator">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EnumVisitorGenerator --version 1.1.2
                    
#r "nuget: EnumVisitorGenerator, 1.1.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EnumVisitorGenerator@1.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EnumVisitorGenerator&version=1.1.2
                    
Install as a Cake Addin
#tool nuget:?package=EnumVisitorGenerator&version=1.1.2
                    
Install as a Cake Tool

EnumVisitorGenerator

If you mark an enum with the [EnumVisitorGenerator.VisitorGenerator] attribute, the source generator will generate several "Visitor" interfaces, where each method will correspond to an item of the target enum. Additionally, an extension class with methods will be generated where the target enum is switched and corresponding visitor interface methods are called.

Installation

PM> NuGet\Install-Package EnumVisitorGenerator

Example

Target Enum

using EnumVisitorGenerator;

namespace SomeNamespace
{
    [VisitorGenerator]
    public enum Color
    {
        Red,
        Green,
        Blue
    }
}

Generated Code

using System;

namespace SomeNamespace
{
    public static class ColorEnumExtension
    {
        public static void Accept(this Color source, IColorVisitor visitor)
        {
            switch (source)
            {
                case Color.Red:
                    visitor.CaseRed();
                    break;
                case Color.Green:
                    visitor.CaseGreen();
                    break;
                case Color.Blue:
                    visitor.CaseBlue();
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(source), source, null);
            }
        }

        public static void Accept<TVisitor>(this Color source, ref TVisitor visitor)
            where TVisitor : struct, IColorVisitor
        {
            switch (source)
            {
                case Color.Red:
                    visitor.CaseRed();
                    break;
                case Color.Green:
                    visitor.CaseGreen();
                    break;
                case Color.Blue:
                    visitor.CaseBlue();
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(source), source, null);
            }
        }

        public static T Accept<T>(this Color source, IColorVisitor<T> visitor)
        {
            switch (source)
            {
                case Color.Red:
                    return visitor.CaseRed();
                case Color.Green:
                    return visitor.CaseGreen();
                case Color.Blue:
                    return visitor.CaseBlue();
                default:
                    throw new ArgumentOutOfRangeException(nameof(source), source, null);
            }
        }

        public static T Accept<T, TVisitor>(this Color source, ref TVisitor visitor)
            where TVisitor : struct, IColorVisitor<T>
        {
            switch (source)
            {
                case Color.Red:
                    return visitor.CaseRed();
                case Color.Green:
                    return visitor.CaseGreen();
                case Color.Blue:
                    return visitor.CaseBlue();
                default:
                    throw new ArgumentOutOfRangeException(nameof(source), source, null);
            }
        }

        public static T Accept<T, TArg>(this Color source, IColorVisitor<T, TArg> visitor, TArg arg)
        {
            switch (source)
            {
                case Color.Red:
                    return visitor.CaseRed(arg);
                case Color.Green:
                    return visitor.CaseGreen(arg);
                case Color.Blue:
                    return visitor.CaseBlue(arg);
                default:
                    throw new ArgumentOutOfRangeException(nameof(source), source, null);
            }
        }

        public static T Accept<T, TVisitor, TArg>(this Color source, ref TVisitor visitor, TArg arg)
            where TVisitor : struct, IColorVisitor<T, TArg>
        {
            switch (source)
            {
                case Color.Red:
                    return visitor.CaseRed(arg);
                case Color.Green:
                    return visitor.CaseGreen(arg);
                case Color.Blue:
                    return visitor.CaseBlue(arg);
                default:
                    throw new ArgumentOutOfRangeException(nameof(source), source, null);
            }
        }
    }

    public interface IColorVisitor
    {
        void CaseRed();
        void CaseGreen();
        void CaseBlue();
    }

    public interface IColorVisitor<out T>
    {
        T CaseRed();
        T CaseGreen();
        T CaseBlue();
    }

    public interface IColorVisitor<out T, in TArg>
    {
        T CaseRed(TArg arg);
        T CaseGreen(TArg arg);
        T CaseBlue(TArg arg);
    }
}

Usage

    class ColorTranslation : IColorVisitor<string, bool>
    {
        public string CaseRed(bool eng) => eng ? "Red" : "Rojo";

        public string CaseGreen(bool eng) => eng ? "Green" : "Verde";

        public string CaseBlue(bool eng) => eng ? "Blue" : "Azul";
    }

...

var translation = new ColorTranslation();
Console.WriteLine(Color.Red.Accept(translation, false));

"Allocation Free" Usage

    struct ColorTranslation : IColorVisitor<string, bool>
    {
        public string CaseRed(bool eng) => eng ? "Red" : "Rojo";

        public string CaseGreen(bool eng) => eng ? "Green" : "Verde";

        public string CaseBlue(bool eng) => eng ? "Blue" : "Azul";
    }
...
var translation = new ColorTranslation();
//boxing does not happen here
Console.WriteLine(Color.Red.Accept<string, ColorTranslation, bool>(ref translation, false));

VisitorToMethod for Stateless Struct Visitors

You can generate a named extension wrapper from a stateless struct visitor:

[VisitorToMethod("GetColor")]
public struct VisitorStruct : IColorVisitor<string, bool>
{
    public string CaseRed(bool eng) => eng ? "Red" : "Rojo";
    public string CaseGreen(bool eng) => eng ? "Green" : "Verde";
    public string CaseBlue(bool eng) => eng ? "Blue" : "Azul";
}

Generated in ColorEnumExtension:

public static string GetColor(this Color source, bool arg)
{
    var visitor = new VisitorStruct();
    return source.Accept<string, VisitorStruct, bool>(ref visitor, arg);
}

If your visitor is IColorVisitor<TResult> (without TArg), the generated method has no extra parameters and calls Accept<TResult, TVisitor>(ref visitor).

If TArg is a value tuple, it is flattened into multiple method parameters and re-packed for Accept.

You can find more details in this article.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.2 86 3/10/2026
1.1.1 88 3/10/2026
1.1.0 126 2/19/2026
1.0.0 365 12/18/2023