RSCG – NetEscapades.EnumGenerators
Running fast tostring and other features for enum
This is how you can use NetEscapades.EnumGenerators .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NetEscapades.EnumGenerators" Version="1.0.0-beta08"
OutputItemType="Analyzer" ReferenceOutputAssembly="false"
PrivateAssets="all" ExcludeAssets="comile;runtime"
/>
</ItemGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
The code that you will use is
var value = InstallType.ShowGUI;
Console.WriteLine($"the enum string is {value.ToStringFast()}");
Console.WriteLine($"{InstallType.None.ToStringFast()}");
var flags = AddToCoffee.Milk | AddToCoffee.Sugar;
Console.WriteLine(flags.ToStringFast());
Console.WriteLine($"HasFlag(Milk), {flags.HasFlagFast(AddToCoffee.Milk)}");
Console.WriteLine($"HasFlag(Biscuit), {flags.HasFlagFast(AddToCoffee.Biscuit)}");
//check also
//InstallTypeExtensions.GetNames
//AddToCoffeeExtensions.GetNames
using NetEscapades.EnumGenerators;
using System.ComponentModel.DataAnnotations;
using System.Xml.Linq;
[EnumExtensions]
internal enum InstallType
{
[Display(Name = $"Please use one of the flags of {nameof(InstallType)}")]
None= 0,
ShowGUI,
ShowNoGui,
}
using NetEscapades.EnumGenerators;
[EnumExtensions]
[Flags]
internal enum AddToCoffee
{
None= 0,
Milk=1,
Sugar=2,
Biscuit=4
}
The code that is generated is
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by the NetEscapades.EnumGenerators source generator
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
using System;
#endif
/// <summary>
/// Extension methods for <see cref="global::AddToCoffee" />
/// </summary>
internal static partial class AddToCoffeeExtensions
{
/// <summary>
/// The number of members in the enum.
/// This is a non-distinct count of defined names.
/// </summary>
public const int Length = 4;
/// <summary>
/// Returns the string representation of the <see cref="global::AddToCoffee"/> value.
/// If the attribute is decorated with a <c>[Display]</c> attribute, then
/// uses the provided value. Otherwise uses the name of the member, equivalent to
/// calling <c>ToString()</c> on <paramref name="value"/>.
/// </summary>
/// <param name="value">The value to retrieve the string value for</param>
/// <returns>The string representation of the value</returns>
public static string ToStringFast(this global::AddToCoffee value)
=> value switch
{
global::AddToCoffee.None => nameof(global::AddToCoffee.None),
global::AddToCoffee.Milk => nameof(global::AddToCoffee.Milk),
global::AddToCoffee.Sugar => nameof(global::AddToCoffee.Sugar),
global::AddToCoffee.Biscuit => nameof(global::AddToCoffee.Biscuit),
_ => value.ToString(),
};
/// <summary>
/// Determines whether one or more bit fields are set in the current instance.
/// Equivalent to calling <see cref="global::System.Enum.HasFlag" /> on <paramref name="value"/>.
/// </summary>
/// <param name="value">The value of the instance to investigate</param>
/// <param name="flag">The flag to check for</param>
/// <returns><c>true</c> if the fields set in the flag are also set in the current instance; otherwise <c>false</c>.</returns>
/// <remarks>If the underlying value of <paramref name="flag"/> is zero, the method returns true.
/// This is consistent with the behaviour of <see cref="global::System.Enum.HasFlag" /></remarks>
public static bool HasFlagFast(this global::AddToCoffee value, global::AddToCoffee flag)
=> flag == 0 ? true : (value & flag) == flag;
/// <summary>
/// Returns a boolean telling whether the given enum value exists in the enumeration.
/// </summary>
/// <param name="value">The value to check if it's defined</param>
/// <returns><c>true</c> if the value exists in the enumeration, <c>false</c> otherwise</returns>
public static bool IsDefined(global::AddToCoffee value)
=> value switch
{
global::AddToCoffee.None => true,
global::AddToCoffee.Milk => true,
global::AddToCoffee.Sugar => true,
global::AddToCoffee.Biscuit => true,
_ => false,
};
/// <summary>
/// Returns a boolean telling whether an enum with the given name exists in the enumeration.
/// </summary>
/// <param name="name">The name to check if it's defined</param>
/// <returns><c>true</c> if a member with the name exists in the enumeration, <c>false</c> otherwise</returns>
public static bool IsDefined(string name) => IsDefined(name, allowMatchingMetadataAttribute: false);
/// <summary>
/// Returns a boolean telling whether an enum with the given name exists in the enumeration,
/// or if a member decorated with a <c>[Display]</c> attribute
/// with the required name exists.
/// </summary>
/// <param name="name">The name to check if it's defined</param>
/// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value of metadata attributes,otherwise ignores them</param>
/// <returns><c>true</c> if a member with the name exists in the enumeration, or a member is decorated
/// with a <c>[Display]</c> attribute with the name, <c>false</c> otherwise</returns>
public static bool IsDefined(string name, bool allowMatchingMetadataAttribute)
{
return name switch
{
nameof(global::AddToCoffee.None) => true,
nameof(global::AddToCoffee.Milk) => true,
nameof(global::AddToCoffee.Sugar) => true,
nameof(global::AddToCoffee.Biscuit) => true,
_ => false,
};
}
#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
/// <summary>
/// Returns a boolean telling whether an enum with the given name exists in the enumeration
/// </summary>
/// <param name="name">The name to check if it's defined</param>
/// <returns><c>true</c> if a member with the name exists in the enumeration, <c>false</c> otherwise</returns>
public static bool IsDefined(in ReadOnlySpan<char> name) => IsDefined(name, allowMatchingMetadataAttribute: false);
/// <summary>
/// Returns a boolean telling whether an enum with the given name exists in the enumeration,
/// or optionally if a member decorated with a <c>[Display]</c> attribute
/// with the required name exists.
/// Slower then the <see cref="IsDefined(string, bool)" /> overload, but doesn't allocate memory./>
/// </summary>
/// <param name="name">The name to check if it's defined</param>
/// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value of metadata attributes,otherwise ignores them</param>
/// <returns><c>true</c> if a member with the name exists in the enumeration, or a member is decorated
/// with a <c>[Display]</c> attribute with the name, <c>false</c> otherwise</returns>
public static bool IsDefined(in ReadOnlySpan<char> name, bool allowMatchingMetadataAttribute)
{
return name switch
{
ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.None).AsSpan(), global::System.StringComparison.Ordinal) => true,
ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Milk).AsSpan(), global::System.StringComparison.Ordinal) => true,
ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Sugar).AsSpan(), global::System.StringComparison.Ordinal) => true,
ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Biscuit).AsSpan(), global::System.StringComparison.Ordinal) => true,
_ => false,
};
}
#endif
/// <summary>
/// Converts the string representation of the name or numeric value of
/// an <see cref="global::AddToCoffee" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The case-sensitive string representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::AddToCoffee" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
string? name,
out global::AddToCoffee value)
=> TryParse(name, out value, false, false);
/// <summary>
/// Converts the string representation of the name or numeric value of
/// an <see cref="global::AddToCoffee" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The string representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::AddToCoffee" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
/// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
string? name,
out global::AddToCoffee value,
bool ignoreCase)
=> TryParse(name, out value, ignoreCase, false);
/// <summary>
/// Converts the string representation of the name or numeric value of
/// an <see cref="global::AddToCoffee" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The string representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::AddToCoffee" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
/// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
/// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value included in metadata attributes such as
/// <c>[Display]</c> attribute when parsing, otherwise only considers the member names.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
string? name,
out global::AddToCoffee value,
bool ignoreCase,
bool allowMatchingMetadataAttribute)
{
if (ignoreCase)
{
switch (name)
{
case string s when s.Equals(nameof(global::AddToCoffee.None), global::System.StringComparison.OrdinalIgnoreCase):
value = global::AddToCoffee.None;
return true;
case string s when s.Equals(nameof(global::AddToCoffee.Milk), global::System.StringComparison.OrdinalIgnoreCase):
value = global::AddToCoffee.Milk;
return true;
case string s when s.Equals(nameof(global::AddToCoffee.Sugar), global::System.StringComparison.OrdinalIgnoreCase):
value = global::AddToCoffee.Sugar;
return true;
case string s when s.Equals(nameof(global::AddToCoffee.Biscuit), global::System.StringComparison.OrdinalIgnoreCase):
value = global::AddToCoffee.Biscuit;
return true;
case string s when int.TryParse(name, out var val):
value = (global::AddToCoffee)val;
return true;
default:
value = default;
return false;
}
}
else
{
switch (name)
{
case nameof(global::AddToCoffee.None):
value = global::AddToCoffee.None;
return true;
case nameof(global::AddToCoffee.Milk):
value = global::AddToCoffee.Milk;
return true;
case nameof(global::AddToCoffee.Sugar):
value = global::AddToCoffee.Sugar;
return true;
case nameof(global::AddToCoffee.Biscuit):
value = global::AddToCoffee.Biscuit;
return true;
case string s when int.TryParse(name, out var val):
value = (global::AddToCoffee)val;
return true;
default:
value = default;
return false;
}
}
}
#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
/// <summary>
/// Converts the span representation of the name or numeric value of
/// an <see cref="global::AddToCoffee" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::AddToCoffee" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
in ReadOnlySpan<char> name,
out global::AddToCoffee value)
=> TryParse(name, out value, false, false);
/// <summary>
/// Converts the span representation of the name or numeric value of
/// an <see cref="global::AddToCoffee" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::AddToCoffee" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
/// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
in ReadOnlySpan<char> name,
out global::AddToCoffee value,
bool ignoreCase)
=> TryParse(name, out value, ignoreCase, false);
/// <summary>
/// Converts the span representation of the name or numeric value of
/// an <see cref="global::AddToCoffee" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
/// <param name="result">When this method returns, contains an object of type
/// <see cref="global::AddToCoffee" /> whose
/// value is represented by <paramref name="result"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::AddToCoffee" />. This parameter is passed uninitialized.</param>
/// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
/// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value included in metadata attributes such as
/// <c>[Display]</c> attribute when parsing, otherwise only considers the member names.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
in ReadOnlySpan<char> name,
out global::AddToCoffee result,
bool ignoreCase,
bool allowMatchingMetadataAttribute)
{
if (ignoreCase)
{
switch (name)
{
case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.None).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
result = global::AddToCoffee.None;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Milk).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
result = global::AddToCoffee.Milk;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Sugar).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
result = global::AddToCoffee.Sugar;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Biscuit).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
result = global::AddToCoffee.Biscuit;
return true;
case ReadOnlySpan<char> current when int.TryParse(name, out var numericResult):
result = (global::AddToCoffee)numericResult;
return true;
default:
result = default;
return false;
}
}
else
{
switch (name)
{
case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.None).AsSpan(), global::System.StringComparison.Ordinal):
result = global::AddToCoffee.None;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Milk).AsSpan(), global::System.StringComparison.Ordinal):
result = global::AddToCoffee.Milk;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Sugar).AsSpan(), global::System.StringComparison.Ordinal):
result = global::AddToCoffee.Sugar;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::AddToCoffee.Biscuit).AsSpan(), global::System.StringComparison.Ordinal):
result = global::AddToCoffee.Biscuit;
return true;
case ReadOnlySpan<char> current when int.TryParse(name, out var numericResult):
result = (global::AddToCoffee)numericResult;
return true;
default:
result = default;
return false;
}
}
}
#endif
/// <summary>
/// Retrieves an array of the values of the members defined in
/// <see cref="global::AddToCoffee" />.
/// Note that this returns a new array with every invocation, so
/// should be cached if appropriate.
/// </summary>
/// <returns>An array of the values defined in <see cref="global::AddToCoffee" /></returns>
public static global::AddToCoffee[] GetValues()
{
return new[]
{
global::AddToCoffee.None,
global::AddToCoffee.Milk,
global::AddToCoffee.Sugar,
global::AddToCoffee.Biscuit,
};
}
/// <summary>
/// Retrieves an array of the names of the members defined in
/// <see cref="global::AddToCoffee" />.
/// Note that this returns a new array with every invocation, so
/// should be cached if appropriate.
/// </summary>
/// <returns>An array of the names of the members defined in <see cref="global::AddToCoffee" /></returns>
public static string[] GetNames()
{
return new[]
{
nameof(global::AddToCoffee.None),
nameof(global::AddToCoffee.Milk),
nameof(global::AddToCoffee.Sugar),
nameof(global::AddToCoffee.Biscuit),
};
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by the NetEscapades.EnumGenerators source generator
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
#if NETESCAPADES_ENUMGENERATORS_EMBED_ATTRIBUTES
namespace NetEscapades.EnumGenerators
{
/// <summary>
/// Add to enums to indicate that extension methods should be generated for the type
/// </summary>
[global::System.AttributeUsage(global::System.AttributeTargets.Enum)]
[global::System.Diagnostics.Conditional("NETESCAPADES_ENUMGENERATORS_USAGES")]
#if NET5_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage(Justification = "Generated by the NetEscapades.EnumGenerators source generator.")]
#else
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
#endif
public class EnumExtensionsAttribute : global::System.Attribute
{
/// <summary>
/// The namespace to generate the extension class.
/// If not provided the namespace of the enum will be used
/// </summary>
public string? ExtensionClassNamespace { get; set; }
/// <summary>
/// The name to use for the extension class.
/// If not provided, the enum name with "Extensions" will be used.
/// For example for an Enum called StatusCodes, the default name
/// will be StatusCodesExtensions
/// </summary>
public string? ExtensionClassName { get; set; }
}
}
#endif
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by the NetEscapades.EnumGenerators source generator
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
using System;
#endif
/// <summary>
/// Extension methods for <see cref="global::InstallType" />
/// </summary>
internal static partial class InstallTypeExtensions
{
/// <summary>
/// The number of members in the enum.
/// This is a non-distinct count of defined names.
/// </summary>
public const int Length = 3;
/// <summary>
/// Returns the string representation of the <see cref="global::InstallType"/> value.
/// If the attribute is decorated with a <c>[Display]</c> attribute, then
/// uses the provided value. Otherwise uses the name of the member, equivalent to
/// calling <c>ToString()</c> on <paramref name="value"/>.
/// </summary>
/// <param name="value">The value to retrieve the string value for</param>
/// <returns>The string representation of the value</returns>
public static string ToStringFast(this global::InstallType value)
=> value switch
{
global::InstallType.None => "Please use one of the flags of InstallType",
global::InstallType.ShowGUI => nameof(global::InstallType.ShowGUI),
global::InstallType.ShowNoGui => nameof(global::InstallType.ShowNoGui),
_ => value.ToString(),
};
/// <summary>
/// Returns a boolean telling whether the given enum value exists in the enumeration.
/// </summary>
/// <param name="value">The value to check if it's defined</param>
/// <returns><c>true</c> if the value exists in the enumeration, <c>false</c> otherwise</returns>
public static bool IsDefined(global::InstallType value)
=> value switch
{
global::InstallType.None => true,
global::InstallType.ShowGUI => true,
global::InstallType.ShowNoGui => true,
_ => false,
};
/// <summary>
/// Returns a boolean telling whether an enum with the given name exists in the enumeration.
/// </summary>
/// <param name="name">The name to check if it's defined</param>
/// <returns><c>true</c> if a member with the name exists in the enumeration, <c>false</c> otherwise</returns>
public static bool IsDefined(string name) => IsDefined(name, allowMatchingMetadataAttribute: false);
/// <summary>
/// Returns a boolean telling whether an enum with the given name exists in the enumeration,
/// or if a member decorated with a <c>[Display]</c> attribute
/// with the required name exists.
/// </summary>
/// <param name="name">The name to check if it's defined</param>
/// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value of metadata attributes,otherwise ignores them</param>
/// <returns><c>true</c> if a member with the name exists in the enumeration, or a member is decorated
/// with a <c>[Display]</c> attribute with the name, <c>false</c> otherwise</returns>
public static bool IsDefined(string name, bool allowMatchingMetadataAttribute)
{
var isDefinedInDisplayAttribute = false;
if (allowMatchingMetadataAttribute)
{
isDefinedInDisplayAttribute = name switch
{
"Please use one of the flags of InstallType" => true,
_ => false,
};
}
if (isDefinedInDisplayAttribute)
{
return true;
}
return name switch
{
nameof(global::InstallType.None) => true,
nameof(global::InstallType.ShowGUI) => true,
nameof(global::InstallType.ShowNoGui) => true,
_ => false,
};
}
#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
/// <summary>
/// Returns a boolean telling whether an enum with the given name exists in the enumeration
/// </summary>
/// <param name="name">The name to check if it's defined</param>
/// <returns><c>true</c> if a member with the name exists in the enumeration, <c>false</c> otherwise</returns>
public static bool IsDefined(in ReadOnlySpan<char> name) => IsDefined(name, allowMatchingMetadataAttribute: false);
/// <summary>
/// Returns a boolean telling whether an enum with the given name exists in the enumeration,
/// or optionally if a member decorated with a <c>[Display]</c> attribute
/// with the required name exists.
/// Slower then the <see cref="IsDefined(string, bool)" /> overload, but doesn't allocate memory./>
/// </summary>
/// <param name="name">The name to check if it's defined</param>
/// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value of metadata attributes,otherwise ignores them</param>
/// <returns><c>true</c> if a member with the name exists in the enumeration, or a member is decorated
/// with a <c>[Display]</c> attribute with the name, <c>false</c> otherwise</returns>
public static bool IsDefined(in ReadOnlySpan<char> name, bool allowMatchingMetadataAttribute)
{
var isDefinedInDisplayAttribute = false;
if (allowMatchingMetadataAttribute)
{
isDefinedInDisplayAttribute = name switch
{
ReadOnlySpan<char> current when current.Equals("Please use one of the flags of InstallType".AsSpan(), global::System.StringComparison.Ordinal) => true,
_ => false,
};
}
if (isDefinedInDisplayAttribute)
{
return true;
}
return name switch
{
ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.None).AsSpan(), global::System.StringComparison.Ordinal) => true,
ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowGUI).AsSpan(), global::System.StringComparison.Ordinal) => true,
ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowNoGui).AsSpan(), global::System.StringComparison.Ordinal) => true,
_ => false,
};
}
#endif
/// <summary>
/// Converts the string representation of the name or numeric value of
/// an <see cref="global::InstallType" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The case-sensitive string representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::InstallType" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
string? name,
out global::InstallType value)
=> TryParse(name, out value, false, false);
/// <summary>
/// Converts the string representation of the name or numeric value of
/// an <see cref="global::InstallType" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The string representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::InstallType" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
/// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
string? name,
out global::InstallType value,
bool ignoreCase)
=> TryParse(name, out value, ignoreCase, false);
/// <summary>
/// Converts the string representation of the name or numeric value of
/// an <see cref="global::InstallType" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The string representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::InstallType" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
/// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
/// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value included in metadata attributes such as
/// <c>[Display]</c> attribute when parsing, otherwise only considers the member names.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
string? name,
out global::InstallType value,
bool ignoreCase,
bool allowMatchingMetadataAttribute)
{
if (allowMatchingMetadataAttribute)
{
if (ignoreCase)
{
switch (name)
{
case string s when s.Equals("Please use one of the flags of InstallType", global::System.StringComparison.OrdinalIgnoreCase):
value = global::InstallType.None;
return true;
default:
break;
};
}
else
{
switch (name)
{
case "Please use one of the flags of InstallType":
value = global::InstallType.None;
return true;
default:
break;
};
}
}
if (ignoreCase)
{
switch (name)
{
case string s when s.Equals(nameof(global::InstallType.None), global::System.StringComparison.OrdinalIgnoreCase):
value = global::InstallType.None;
return true;
case string s when s.Equals(nameof(global::InstallType.ShowGUI), global::System.StringComparison.OrdinalIgnoreCase):
value = global::InstallType.ShowGUI;
return true;
case string s when s.Equals(nameof(global::InstallType.ShowNoGui), global::System.StringComparison.OrdinalIgnoreCase):
value = global::InstallType.ShowNoGui;
return true;
case string s when int.TryParse(name, out var val):
value = (global::InstallType)val;
return true;
default:
value = default;
return false;
}
}
else
{
switch (name)
{
case nameof(global::InstallType.None):
value = global::InstallType.None;
return true;
case nameof(global::InstallType.ShowGUI):
value = global::InstallType.ShowGUI;
return true;
case nameof(global::InstallType.ShowNoGui):
value = global::InstallType.ShowNoGui;
return true;
case string s when int.TryParse(name, out var val):
value = (global::InstallType)val;
return true;
default:
value = default;
return false;
}
}
}
#if NETCOREAPP && !NETCOREAPP2_0 && !NETCOREAPP1_1 && !NETCOREAPP1_0
/// <summary>
/// Converts the span representation of the name or numeric value of
/// an <see cref="global::InstallType" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::InstallType" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
in ReadOnlySpan<char> name,
out global::InstallType value)
=> TryParse(name, out value, false, false);
/// <summary>
/// Converts the span representation of the name or numeric value of
/// an <see cref="global::InstallType" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
/// <param name="value">When this method returns, contains an object of type
/// <see cref="global::InstallType" /> whose
/// value is represented by <paramref name="value"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
/// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
in ReadOnlySpan<char> name,
out global::InstallType value,
bool ignoreCase)
=> TryParse(name, out value, ignoreCase, false);
/// <summary>
/// Converts the span representation of the name or numeric value of
/// an <see cref="global::InstallType" /> to the equivalent instance.
/// The return value indicates whether the conversion succeeded.
/// </summary>
/// <param name="name">The span representation of the enumeration name or underlying value to convert</param>
/// <param name="result">When this method returns, contains an object of type
/// <see cref="global::InstallType" /> whose
/// value is represented by <paramref name="result"/> if the parse operation succeeds.
/// If the parse operation fails, contains the default value of the underlying type
/// of <see cref="global::InstallType" />. This parameter is passed uninitialized.</param>
/// <param name="ignoreCase"><c>true</c> to read value in case insensitive mode; <c>false</c> to read value in case sensitive mode.</param>
/// <param name="allowMatchingMetadataAttribute">If <c>true</c>, considers the value included in metadata attributes such as
/// <c>[Display]</c> attribute when parsing, otherwise only considers the member names.</param>
/// <returns><c>true</c> if the value parameter was converted successfully; otherwise, <c>false</c>.</returns>
public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
in ReadOnlySpan<char> name,
out global::InstallType result,
bool ignoreCase,
bool allowMatchingMetadataAttribute)
{
if (allowMatchingMetadataAttribute)
{
if (ignoreCase)
{
switch (name)
{
case ReadOnlySpan<char> current when current.Equals("Please use one of the flags of InstallType".AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
result = global::InstallType.None;
return true;
default:
break;
};
}
else
{
switch (name)
{
case ReadOnlySpan<char> current when current.Equals("Please use one of the flags of InstallType".AsSpan(), global::System.StringComparison.Ordinal):
result = global::InstallType.None;
return true;
default:
break;
};
}
}
if (ignoreCase)
{
switch (name)
{
case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.None).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
result = global::InstallType.None;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowGUI).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
result = global::InstallType.ShowGUI;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowNoGui).AsSpan(), global::System.StringComparison.OrdinalIgnoreCase):
result = global::InstallType.ShowNoGui;
return true;
case ReadOnlySpan<char> current when int.TryParse(name, out var numericResult):
result = (global::InstallType)numericResult;
return true;
default:
result = default;
return false;
}
}
else
{
switch (name)
{
case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.None).AsSpan(), global::System.StringComparison.Ordinal):
result = global::InstallType.None;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowGUI).AsSpan(), global::System.StringComparison.Ordinal):
result = global::InstallType.ShowGUI;
return true;
case ReadOnlySpan<char> current when current.Equals(nameof(global::InstallType.ShowNoGui).AsSpan(), global::System.StringComparison.Ordinal):
result = global::InstallType.ShowNoGui;
return true;
case ReadOnlySpan<char> current when int.TryParse(name, out var numericResult):
result = (global::InstallType)numericResult;
return true;
default:
result = default;
return false;
}
}
}
#endif
/// <summary>
/// Retrieves an array of the values of the members defined in
/// <see cref="global::InstallType" />.
/// Note that this returns a new array with every invocation, so
/// should be cached if appropriate.
/// </summary>
/// <returns>An array of the values defined in <see cref="global::InstallType" /></returns>
public static global::InstallType[] GetValues()
{
return new[]
{
global::InstallType.None,
global::InstallType.ShowGUI,
global::InstallType.ShowNoGui,
};
}
/// <summary>
/// Retrieves an array of the names of the members defined in
/// <see cref="global::InstallType" />.
/// Note that this returns a new array with every invocation, so
/// should be cached if appropriate.
/// </summary>
/// <returns>An array of the names of the members defined in <see cref="global::InstallType" /></returns>
public static string[] GetNames()
{
return new[]
{
nameof(global::InstallType.None),
nameof(global::InstallType.ShowGUI),
nameof(global::InstallType.ShowNoGui),
};
}
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/NetEscapades.EnumGenerators