I have a code that heavily relies on various enums.
Now I'm in a situation that these enums are stored in a database tables with ID colum for values and nvarchar for string representation of enum names.
The enum types (table names) are known at the compile time, the names and values are not.
I need to make the enum dependent code work with the values retrieved from database in a Entity Framework Core app, making as few changes as possible.
I'm trying to come up with a dynamic object that works like enum and has a similar syntax, in particular, I'd like to keep dot notation.
Below is what I came up so far. What do you think? Is there a simpler type I could use?
Example of usage:
Now I'm in a situation that these enums are stored in a database tables with ID colum for values and nvarchar for string representation of enum names.
The enum types (table names) are known at the compile time, the names and values are not.
I need to make the enum dependent code work with the values retrieved from database in a Entity Framework Core app, making as few changes as possible.
I'm trying to come up with a dynamic object that works like enum and has a similar syntax, in particular, I'd like to keep dot notation.
Below is what I came up so far. What do you think? Is there a simpler type I could use?
C#:
// to use as a common type, similar to Dictionary<Enum, string>
internal interface IEnum { }
public class SomeEnum : IEnum
{
// to use dot notation
static internal readonly dynamic v = new ExpandoObject();
// to dynamically create properties from strings on v
static readonly IDictionary<string, object?> iDict = (v as IDictionary<string, object?>)!;
// to avoid boxing/unboxing while checking existing key/values
static readonly Dictionary<string, int> dict = new();
static internal void Init(Dictionary<string, int> _dict)
{
foreach (var (k, v) in _dict)
{
iDict[k] = v;
dict[k] = v;
}
}
string _name = "";
int _value;
internal string Name {
get => _name;
set
{
if (!dict.ContainsKey(value))
throw new NotImplementedException($"SomeEnum.Name.set : '{value}' not present in dictionary");
_name = value;
_value = dict[value];
}
}
internal int Value
{
get => _value;
set
{
var name = dict.FirstOrDefault(p => p.Value == value).Key ??
throw new NotImplementedException($"SomeEnum.Value.set : '{value}' not present in dictionary");
_name = name;
_value = value;
}
}
internal SomeEnum(int _value)
{
Value = _value;
}
internal SomeEnum(string _name)
{
Name = _name;
}
public override string ToString() => $"Name: {Name}, Value: {Value}";
}
Example of usage:
C#:
SomeEnum.Init(new Dictionary<string, int>
{
{ "None", 0 },
{ "Left_Side", 1},
{ "Right_Side", 2}
});
var someEnum = new SomeEnum(SomeEnum.v.Left_Side);
Console.WriteLine(someEnum);
var someEnum2 = new SomeEnum(SomeEnum.v.Right_Side);
someEnum.Value = SomeEnum.v.None;
Console.WriteLine(someEnum);