EnumDescription
IEnumDescription describes an enum type.
/// <summary>Description of an enum type.</summary>
/// <remarks>See Avalanche.Message.Localization for localizing <see cref="IEnumDescription"/>.</remarks>
public interface IEnumDescription
{
/// <summary>Underlying type</summary>
Type ItemType { get; set; }
/// <summary>Flag operations. Null if enum is not [Flags] usable.</summary>
IEnumFlagOperations<object>? Flags { get; set; }
/// <summary>Details about each item.</summary>
IList<IEnumItem<object>> Items { get; set; }
}
IEnumFlagOperations describes an enum flag operations.
/// <summary>Enumeration flag operations</summary>
public interface IEnumFlagOperations<T>
{
/// <summary>Underlying type</summary>
Type Type { get; set; }
/// <summary>Get-or-create default value.</summary>
T Default { get; set; }
/// <summary>Test whether <paramref name="enumValue"/> has any of the flags in <paramref name="flags"/>.</summary>
bool HasAny(T @enumValue, T flags);
/// <summary>Test whether <paramref name="enumValue"/> has all of the flags in <paramref name="flags"/>.</summary>
bool HasAll(T @enumValue, T flags);
/// <summary>Intersection of <paramref name="value1"/> and <paramref name="value2"/></summary>
T Intersection(T value1, T value2);
/// <summary>Union of <paramref name="value1"/> and <paramref name="value2"/></summary>
T Union(T value1, T value2);
}
IEnumItem describes an enum item.
/// <summary>Enum item description</summary>
public interface IEnumItem<T>
{
/// <summary>Key, typically "Class:Field".</summary>
string Key { get; set; }
/// <summary>Enumeration item name, part of full key.</summary>
string Name { get; set; }
/// <summary>Object that prints label when ToString() is called. May implement <see cref="IFormattable"/> or <see cref="ISpanFormattable"/> for culture specific formatting.</summary>
object Label { get; set; }
/// <summary>Value, such as <see cref="string"/>.</summary>
T Value { get; set; }
}
EnumDescription.CreateForEnumType(type) creates description for an enum type.
// Create IEnumDescription
IEnumDescription enumDescription = EnumDescription.CreateForEnumType(typeof(LanguageEnum));
// Print items
foreach (IEnumItem<object> item in enumDescription.Items) Console.WriteLine(item.Name);
[Flags]
public enum LanguageEnum
{
Finnish = 1 << 0,
Swedish = 1 << 1,
Norwegian = 1 << 2
}
[EnumOf] indicates that type contains an enum.
public record MyRecord200
{
[EnumOf<string, Languages>(isFlags: true)]
public string Languages { get; set; } = "Finnish";
}
public class Languages : IEnumerable<IEnumItem<object>>
{
IEnumItem<object>[] content = new IEnumItem<object>[] {
new EnumItem("Languages:Finnish", "Finnish", "Finnish", "Finnish"),
new EnumItem("Languages:Swedish", "Swedish", "Swedish", "Swedish"),
new EnumItem("Languages:Norwegian", "Norwegian", "Norwegian", "Norwegian"),
};
public IEnumerator<IEnumItem<object>> GetEnumerator() => ((IEnumerable<IEnumItem<object>>)content).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => content.GetEnumerator();
}
EnumDescription.CreateForEnumOf(enumOfAttribute) creates description for [EnumOf<,>] attribute.
// Get [EnumOf]
EnumOfAttribute enumOf = typeof(MyRecord200)
.GetProperty(nameof(MyRecord200.Languages))!
.GetCustomAttribute<EnumOfAttribute>()!;
// Create IEnumDescription
IEnumDescription enumDescription = EnumDescription.CreateForEnumOf(enumOf, null);
// Print items
foreach (IEnumItem<object> item in enumDescription.Items) Console.WriteLine(item.Name);
If EnumOfAttribute enumerable is interface, then enum items can be supplied to dependency injection.
// Create dependency injection
IServiceProvider services = new ServiceCollection()
.AddSingleton<ICountries, Countries>()
.BuildServiceProvider();
// Get [EnumOf]
EnumOfAttribute enumOf = typeof(MyRecord203)
.GetProperty(nameof(MyRecord203.Countries))!
.GetCustomAttribute<EnumOfAttribute>()!;
// Create IEnumDescription
IEnumDescription enumDescription = EnumDescription.CreateForEnumOf(enumOf, services);
// Print items
foreach (IEnumItem<object> item in enumDescription.Items) Console.WriteLine(item.Name);
public record MyRecord203
{
[EnumOf<string, ICountries>(isFlags: true)]
public string Countries { get; set; } = "Finland";
}
public interface ICountries : IEnumerable<IEnumItem<object>> { }
public class Countries : ICountries
{
IEnumItem<object>[] content = new IEnumItem<object>[]
{
new EnumItem<string>("Countries:Finland", "Finland", "Finland", "Finland"),
new EnumItem<string>("Countries:Sweden", "Sweden", "Sweden", "Sweden"),
new EnumItem<string>("Countries:Norway", "Norway", "Norway", "Norway"),
};
public IEnumerator<IEnumItem<object>> GetEnumerator() => ((IEnumerable<IEnumItem<object>>)content).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => content.GetEnumerator();
}
IEnumFlagOperations can create unions, intersections and test flags.
// Get cached IEnumDescription
IEnumDescription enumDescription = EnumDescription.Cached[typeof(LanguageEnum)];
// Choose one item
LanguageEnum language = (LanguageEnum)enumDescription.Items[0].Value;
// Take union
LanguageEnum language2 = (LanguageEnum)enumDescription.Flags!.Union(enumDescription.Items[0].Value, enumDescription.Items[1].Value);
// Take intersection
LanguageEnum language3 = (LanguageEnum)enumDescription.Flags!.Intersection(language, language2);
// Test flag
bool gotOne = enumDescription.Flags!.HasAny(language2, enumDescription.Items[1].Value);
bool gotAll = enumDescription.Flags!.HasAll(language2, enumDescription.Items[1].Value);
Full Example
Full example
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using Avalanche.Utilities;
using Microsoft.Extensions.DependencyInjection;
public class enumdescription
{
public static void Run()
{
{
// <01>
// Create IEnumDescription
IEnumDescription enumDescription = EnumDescription.CreateForEnumType(typeof(LanguageEnum));
// Print items
foreach (IEnumItem<object> item in enumDescription.Items) Console.WriteLine(item.Name);
// </01>
}
{
// <02>
// Get [EnumOf]
EnumOfAttribute enumOf = typeof(MyRecord200)
.GetProperty(nameof(MyRecord200.Languages))!
.GetCustomAttribute<EnumOfAttribute>()!;
// Create IEnumDescription
IEnumDescription enumDescription = EnumDescription.CreateForEnumOf(enumOf, null);
// Print items
foreach (IEnumItem<object> item in enumDescription.Items) Console.WriteLine(item.Name);
// </02>
}
{
// <03>
// Create dependency injection
IServiceProvider services = new ServiceCollection()
.AddSingleton<ICountries, Countries>()
.BuildServiceProvider();
// Get [EnumOf]
EnumOfAttribute enumOf = typeof(MyRecord203)
.GetProperty(nameof(MyRecord203.Countries))!
.GetCustomAttribute<EnumOfAttribute>()!;
// Create IEnumDescription
IEnumDescription enumDescription = EnumDescription.CreateForEnumOf(enumOf, services);
// Print items
foreach (IEnumItem<object> item in enumDescription.Items) Console.WriteLine(item.Name);
// </03>
}
{
// <04>
// Get cached IEnumDescription
IEnumDescription enumDescription = EnumDescription.Cached[typeof(LanguageEnum)];
// Choose one item
LanguageEnum language = (LanguageEnum)enumDescription.Items[0].Value;
// Take union
LanguageEnum language2 = (LanguageEnum)enumDescription.Flags!.Union(enumDescription.Items[0].Value, enumDescription.Items[1].Value);
// Take intersection
LanguageEnum language3 = (LanguageEnum)enumDescription.Flags!.Intersection(language, language2);
// Test flag
bool gotOne = enumDescription.Flags!.HasAny(language2, enumDescription.Items[1].Value);
bool gotAll = enumDescription.Flags!.HasAll(language2, enumDescription.Items[1].Value);
// </04>
}
}
}
// <02B>
public record MyRecord200
{
[EnumOf<string, Languages>(isFlags: true)]
public string Languages { get; set; } = "Finnish";
}
public class Languages : IEnumerable<IEnumItem<object>>
{
IEnumItem<object>[] content = new IEnumItem<object>[] {
new EnumItem("Languages:Finnish", "Finnish", "Finnish", "Finnish"),
new EnumItem("Languages:Swedish", "Swedish", "Swedish", "Swedish"),
new EnumItem("Languages:Norwegian", "Norwegian", "Norwegian", "Norwegian"),
};
public IEnumerator<IEnumItem<object>> GetEnumerator() => ((IEnumerable<IEnumItem<object>>)content).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => content.GetEnumerator();
}
// </02B>
// <01B>
[Flags]
public enum LanguageEnum
{
Finnish = 1 << 0,
Swedish = 1 << 1,
Norwegian = 1 << 2
}
// </01B>
// <03B>
public record MyRecord203
{
[EnumOf<string, ICountries>(isFlags: true)]
public string Countries { get; set; } = "Finland";
}
public interface ICountries : IEnumerable<IEnumItem<object>> { }
public class Countries : ICountries
{
IEnumItem<object>[] content = new IEnumItem<object>[]
{
new EnumItem<string>("Countries:Finland", "Finland", "Finland", "Finland"),
new EnumItem<string>("Countries:Sweden", "Sweden", "Sweden", "Sweden"),
new EnumItem<string>("Countries:Norway", "Norway", "Norway", "Norway"),
};
public IEnumerator<IEnumItem<object>> GetEnumerator() => ((IEnumerable<IEnumItem<object>>)content).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => content.GetEnumerator();
}
// </03B>