RSCG – TaggedEnum
| name | TaggedEnum |
| nuget | https://www.nuget.org/packages/TaggedEnum/ |
| link | https://github.com/al0rid4l/SixTatami |
| author | Alor’idal |
Generates dictionary-based lookup, fast string conversion, and name/value retrieval for enums with custom data tags — like tagged unions for enums.
How to use
1. Decorate with Tagged and attach Data to each member:
“`csharp
[Tagged]
public enum CarTypes
{
[Data(“this is none”)] None,
[Data(“this is dacia”)] Dacia,
[Data(“this is bmw”)] BMW,
[Data(“this is mercedes”)]Mercedes,
}
“`
2 Use generated extensions:
“`charp
CarTypes.None.ToStringFast(); // “None”
CarTypes.None.Data; // “this is none”
EnumDemoCarTypesExtension.TryGetValueByName(“None”, out _); // true
“`
You can use for Fast ToString() without reflection, attaching metadata to enum values via [Data], name-based lookup, and JSON serializer extensions for enums.
This is how you can use TaggedEnum .
The code that you start with is
<project sdk="Microsoft.NET.Sdk">
<propertygroup>
<outputtype>Exe</outputtype>
<targetframework>net10.0</targetframework>
<implicitusings>enable</implicitusings>
<nullable>enable</nullable>
</propertygroup>
<propertygroup>
<emitcompilergeneratedfiles>true</emitcompilergeneratedfiles>
<compilergeneratedfilesoutputpath>$(BaseIntermediateOutputPath)\GX</compilergeneratedfilesoutputpath>
</propertygroup>
<itemgroup>
<packagereference version="2.0.1" include="TaggedEnum">
</packagereference>
</itemgroup>
The code that you will use is
// See https://aka.ms/new-console-template for more information
using EnumDemo;
Console.WriteLine("Hello, World!");
Console.WriteLine(CarTypes.None.ToStringFast());
Console.WriteLine(CarTypes.None.Data);
Console.WriteLine(EnumDemoCarTypesExtension.TryGetValueByName("None",out _));
//Console.WriteLine("Car types:" + CarTypesEnumExtensions.GetValues().Count);
//var cars = CarTypesEnumExtensions.GetValues();
//foreach (var car in cars)
//{
// Console.WriteLine(car.ToStringFast());
//}
using TaggedEnum;
namespace EnumDemo;
[Tagged]
public enum CarTypes
{
[Data("this is none")]
None,
[Data("this is dacia")]
Dacia,
[Data("this is tesla")]
Tesla,
[Data("this is bwm")]
BMW,
[Data("this is mercedes")]
Mercedes,
}
The code that is generated is
// <auto-generated>
#nullable enable
using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;
using TaggedEnum;
namespace EnumDemo;
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public static class EnumDemoCarTypesExtension {
private static readonly Dictionary<global::enumdemo.cartypes , string=""> ValueNameMap = new(new EnumDemoCarTypesComparer()) {
{global::EnumDemo.CarTypes.None, "None"},
{global::EnumDemo.CarTypes.Dacia, "Dacia"},
{global::EnumDemo.CarTypes.Tesla, "Tesla"},
{global::EnumDemo.CarTypes.BMW, "BMW"},
{global::EnumDemo.CarTypes.Mercedes, "Mercedes"},
};
extension(global::EnumDemo.CarTypes self) {
public string Data {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
get =>
self switch {
global::EnumDemo.CarTypes.None => (string)"this is none",
global::EnumDemo.CarTypes.Dacia => (string)"this is dacia",
global::EnumDemo.CarTypes.Tesla => (string)"this is tesla",
global::EnumDemo.CarTypes.BMW => (string)"this is bwm",
global::EnumDemo.CarTypes.Mercedes => (string)"this is mercedes",
_ => DataNotFoundException.ThrowWithMessage<string>($"Data of {ValueNameMap[self]} not found.")
};
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public static string ToStringFast(this global::EnumDemo.CarTypes self)
=> self switch {
global::EnumDemo.CarTypes.None => "None",
global::EnumDemo.CarTypes.Dacia => "Dacia",
global::EnumDemo.CarTypes.Tesla => "Tesla",
global::EnumDemo.CarTypes.BMW => "BMW",
global::EnumDemo.CarTypes.Mercedes => "Mercedes",
_ => UnreachableException.ThrowWithMessage<string>("Never reach here.")
};
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public static bool HasName(this global::EnumDemo.CarTypes self, string name)
=> self.ToStringFast() == name;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public static bool HasData(this global::EnumDemo.CarTypes self, string data)
=> self.Data == data;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public static bool Equals(this global::EnumDemo.CarTypes self, global::EnumDemo.CarTypes v)
=> self == v;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public static bool TryGetDataByName(string name, [NotNullWhen(true)]out string? v) {
v = name switch {
"None" => (string)"this is none",
"Dacia" => (string)"this is dacia",
"Tesla" => (string)"this is tesla",
"BMW" => (string)"this is bwm",
"Mercedes" => (string)"this is mercedes",
_ => null
};
return v is not null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public static bool TryGetValueByName(string name, [NotNullWhen(true)]out global::EnumDemo.CarTypes? v) {
v = name switch {
"None" => global::EnumDemo.CarTypes.None,
"Dacia" => global::EnumDemo.CarTypes.Dacia,
"Tesla" => global::EnumDemo.CarTypes.Tesla,
"BMW" => global::EnumDemo.CarTypes.BMW,
"Mercedes" => global::EnumDemo.CarTypes.Mercedes,
_ => null
};
return v is not null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public static bool TryGetValueByData(string data, [NotNullWhen(true)]out global::EnumDemo.CarTypes? v) {
v = data switch {
(string)"this is none" => global::EnumDemo.CarTypes.None,
(string)"this is dacia" => global::EnumDemo.CarTypes.Dacia,
(string)"this is tesla" => global::EnumDemo.CarTypes.Tesla,
(string)"this is bwm" => global::EnumDemo.CarTypes.BMW,
(string)"this is mercedes" => global::EnumDemo.CarTypes.Mercedes,
_ => null
};
return v is not null;
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
internal sealed class EnumDemoCarTypesComparer: IEqualityComparer<global::enumdemo.cartypes> {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(global::EnumDemo.CarTypes x, global::EnumDemo.CarTypes y) => x == y;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetHashCode([DisallowNull] global::EnumDemo.CarTypes obj) => (int)obj;
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
internal sealed class EnumDemoCarTypesstringComparer: IEqualityComparer<string> {
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(string? x, string? y) => x == y;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetHashCode([DisallowNull] string obj) => obj.GetHashCode();
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesToDataConverter: JsonConverter<global::enumdemo.cartypes> {
public override global::EnumDemo.CarTypes Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
string? token = reader.GetString();
return string.IsNullOrEmpty(token)
? JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't convert data \"{token}\" to global::EnumDemo.CarTypes.")
: EnumDemoCarTypesExtension.TryGetValueByData(token, out var result)
? result.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{token}\" in global::EnumDemo.CarTypes data.");
}
public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes value, JsonSerializerOptions options) {
writer.WriteStringValue(value.Data);
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesArrayToDataArrayConverter: JsonConverter<global::enumdemo.cartypes []> {
public override global::EnumDemo.CarTypes[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var list = new List<global::enumdemo.cartypes>();
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.StartArray:
continue;
case JsonTokenType.EndArray:
goto label;
case JsonTokenType.String:
var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
list.Add(EnumDemoCarTypesExtension.TryGetValueByData(
v,
out var item)
? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes data."));
continue;
default:
continue;
}
}
label:
return list.ToArray();
}
public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes[] arr, JsonSerializerOptions options) {
writer.WriteStartArray();
for (int i = 0, len = arr.Length; i < len; ++i) {
writer.WriteStringValue(arr[i].Data);
}
writer.WriteEndArray();
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class NullableEnumDemoCarTypesArrayToDataArrayConverter: JsonConverter<global::enumdemo.cartypes ?[]> {
public override global::EnumDemo.CarTypes?[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var list = new List<global::enumdemo.cartypes ?>();
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.StartArray:
continue;
case JsonTokenType.EndArray:
goto label;
case JsonTokenType.Null:
list.Add(null);
continue;
case JsonTokenType.String:
var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
list.Add(EnumDemoCarTypesExtension.TryGetValueByData(
v,
out var item)
? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes data."));
continue;
default:
continue;
}
}
label:
return list.ToArray();
}
public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes?[] arr, JsonSerializerOptions options) {
writer.WriteStartArray();
for (int i = 0, len = arr.Length; i < len; ++i) {
var v = arr[i];
if (v is null) {
writer.WriteNullValue();
} else {
writer.WriteStringValue(v.Value.Data);
}
}
writer.WriteEndArray();
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesEnumerableToDataEnumerableConverter: JsonConverter<ienumerable><global::enumdemo.cartypes>> {
public override IEnumerable<global::enumdemo.cartypes> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var list = new List<global::enumdemo.cartypes>();
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.StartArray:
continue;
case JsonTokenType.EndArray:
goto label;
case JsonTokenType.String:
var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
list.Add(EnumDemoCarTypesExtension.TryGetValueByData(
v,
out var item)
? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes data."));
continue;
default:
continue;
}
}
label:
return list.ToArray();
}
public override void Write(Utf8JsonWriter writer, IEnumerable<global::enumdemo.cartypes> values, JsonSerializerOptions options) {
writer.WriteStartArray();
foreach (var v in values) {
writer.WriteStringValue(v.Data);
}
writer.WriteEndArray();
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class NullableEnumDemoCarTypesEnumerableToDataEnumerableConverter: JsonConverter<ienumerable><global::enumdemo.cartypes ?>> {
public override IEnumerable<global::enumdemo.cartypes ?> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var list = new List<global::enumdemo.cartypes ?>();
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.StartArray:
continue;
case JsonTokenType.EndArray:
goto label;
case JsonTokenType.Null:
list.Add(null);
continue;
case JsonTokenType.String:
var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
list.Add(EnumDemoCarTypesExtension.TryGetValueByData(
v,
out var item)
? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes data."));
continue;
default:
continue;
}
}
label:
return list.ToArray();
}
public override void Write(Utf8JsonWriter writer, IEnumerable<global::enumdemo.cartypes ?> values, JsonSerializerOptions options) {
writer.WriteStartArray();
foreach (var v in values) {
if (v is null) {
writer.WriteNullValue();
} else {
writer.WriteStringValue(v.Value.Data);
}
}
writer.WriteEndArray();
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesToNameConverter: JsonConverter<global::enumdemo.cartypes> {
public override global::EnumDemo.CarTypes Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
string? token = reader.GetString();
return string.IsNullOrEmpty(token)
? JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't convert name \"{token}\" to global::EnumDemo.CarTypes.")
: EnumDemoCarTypesExtension.TryGetValueByName(token, out var result)
? result.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{token}\" in global::EnumDemo.CarTypes name.");
}
public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes value, JsonSerializerOptions options) {
writer.WriteStringValue(value.ToStringFast());
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesArrayToNameArrayConverter: JsonConverter<global::enumdemo.cartypes []> {
public override global::EnumDemo.CarTypes[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var list = new List<global::enumdemo.cartypes>();
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.StartArray:
continue;
case JsonTokenType.EndArray:
goto label;
case JsonTokenType.String:
var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
list.Add(EnumDemoCarTypesExtension.TryGetValueByName(
v,
out var item)
? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes name."));
continue;
default:
continue;
}
}
label:
return list.ToArray();
}
public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes[] arr, JsonSerializerOptions options) {
writer.WriteStartArray();
for (int i = 0, len = arr.Length; i < len; ++i) {
writer.WriteStringValue(arr[i].ToStringFast());
}
writer.WriteEndArray();
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class NullableEnumDemoCarTypesArrayToNameArrayConverter: JsonConverter<global::enumdemo.cartypes ?[]> {
public override global::EnumDemo.CarTypes?[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var list = new List<global::enumdemo.cartypes ?>();
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.StartArray:
continue;
case JsonTokenType.EndArray:
goto label;
case JsonTokenType.Null:
list.Add(null);
continue;
case JsonTokenType.String:
var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
list.Add(EnumDemoCarTypesExtension.TryGetValueByName(
v,
out var item)
? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes name."));
continue;
default:
continue;
}
}
label:
return list.ToArray();
}
public override void Write(Utf8JsonWriter writer, global::EnumDemo.CarTypes?[] arr, JsonSerializerOptions options) {
writer.WriteStartArray();
for (int i = 0, len = arr.Length; i < len; ++i) {
var v = arr[i];
if (v is null) {
writer.WriteNullValue();
} else {
writer.WriteStringValue(v.Value.ToStringFast());
}
}
writer.WriteEndArray();
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class EnumDemoCarTypesEnumerableToNameEnumerableConverter: JsonConverter<ienumerable><global::enumdemo.cartypes>> {
public override IEnumerable<global::enumdemo.cartypes> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var list = new List<global::enumdemo.cartypes>();
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.StartArray:
continue;
case JsonTokenType.EndArray:
goto label;
case JsonTokenType.String:
var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
list.Add(EnumDemoCarTypesExtension.TryGetValueByName(
v,
out var item)
? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes name."));
continue;
default:
continue;
}
}
label:
return list.ToArray();
}
public override void Write(Utf8JsonWriter writer, IEnumerable<global::enumdemo.cartypes> values, JsonSerializerOptions options) {
writer.WriteStartArray();
foreach (var v in values) {
writer.WriteStringValue(v.ToStringFast());
}
writer.WriteEndArray();
}
}
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("TaggedEnum", "1.0")]
public sealed class NullableEnumDemoCarTypesEnumerableToNameEnumerableConverter: JsonConverter<ienumerable><global::enumdemo.cartypes ?>> {
public override IEnumerable<global::enumdemo.cartypes ?> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
var list = new List<global::enumdemo.cartypes ?>();
while (reader.Read()) {
switch (reader.TokenType) {
case JsonTokenType.StartArray:
continue;
case JsonTokenType.EndArray:
goto label;
case JsonTokenType.Null:
list.Add(null);
continue;
case JsonTokenType.String:
var v = reader.GetString() is not {} token ? UnreachableException.ThrowWithMessage<string>("JsonTokenType is string but reader.GetString() is null.") : token;
list.Add(EnumDemoCarTypesExtension.TryGetValueByName(
v,
out var item)
? item!.Value : JsonException.ThrowWithMessage<global::enumdemo.cartypes>($"Couldn't find \"{v}\" in global::EnumDemo.CarTypes name."));
continue;
default:
continue;
}
}
label:
return list.ToArray();
}
public override void Write(Utf8JsonWriter writer, IEnumerable<global::enumdemo.cartypes ?> values, JsonSerializerOptions options) {
writer.WriteStartArray();
foreach (var v in values) {
if (v is null) {
writer.WriteNullValue();
} else {
writer.WriteStringValue(v.Value.ToStringFast());
}
}
writer.WriteEndArray();
}
}
// <auto-generated>
#nullable enable
using System.Text.Json;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace TaggedEnum;
internal static class JsonExceptionExtensions {
extension(JsonException) {
[DoesNotReturn]
public static T ThrowWithMessage<t>(string msg)
=> throw new JsonException(msg);
}
}
internal static class UnreachableExceptionExtensions {
extension(UnreachableException) {
[DoesNotReturn]
public static T ThrowWithMessage<t>(string msg)
=> throw new UnreachableException(msg);
}
}
#pragma warning disable CA1050 // Declare types in namespaces
[AttributeUsage(
AttributeTargets.Field,
Inherited = false,
AllowMultiple = false
)]
internal sealed class Data<tvalue>(TValue v): Attribute {
public TValue V { get; private set; } = v;
}
[AttributeUsage(
AttributeTargets.Field,
Inherited = false,
AllowMultiple = false
)]
// TValue default is string
internal sealed class Data: Attribute {
public object? V { get; }
public Data(object str) {
V = str;
}
public Data() {}
}
#pragma warning restore CA1050 // Declare types in namespaces
#pragma warning disable CA1050 // Declare types in namespaces
[AttributeUsage(
AttributeTargets.Enum,
Inherited = false,
AllowMultiple = false
)]
internal sealed class Tagged<tvalue>: Attribute {
public bool Inline = true;
public bool UseSwitch = true;
public bool AllowDuplicate = false;
}
[AttributeUsage(
AttributeTargets.Enum,
Inherited = false,
AllowMultiple = false
)]
// TValue default is string
internal sealed class Tagged: Attribute {
public bool UseAll = false;
public bool Inline = true;
public bool UseSwitch = true;
public bool AllowDuplicate = false;
}
#pragma warning restore CA1050 // Declare types in namespaces
public sealed class DataNotFoundException(string msg): Exception(msg) {
[DoesNotReturn]
public static T ThrowWithMessage<t>(string message) => throw new DataNotFoundException(message);
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/TaggedEnum