You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Would it be possible to add support for the EnumMember attribute?
[EnumExtensions]
enum UserTypeTest
{
[Display(Name = "مرد")]
[EnumMember(Value = "men_value")]
Men,
[Display(Name = "زن")]
[EnumMember(Value = "women_value")]
Women,
//[Display(Name = "نامشخص")]
None
}
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
var canParse = UserTypeTestExtensions.TryParse("men_value", out var parsed);
if (canParse)
{
Console.WriteLine($"Parsed men_value as {parsed}");
}
else
{
Console.WriteLine("Unable to parse using EnumMember attribute");
}
// ideally something like this that would return string values: men_value, women_value
var allValues = UserTypeTestExtensions.GetValues();
// ideally something like this for fetching the actual Value that is set: men_value or women_value based on actual enum
// var value = UserTypeTest.Men.ToValueFast();
}
}
Use Case
For our use case, we have DTO classes that are mapped from JSON and validated
{
"npc_gender": "men_value",
}
class RequestDto
{
[JsonPropertyName("npc_gender")]
public string? NpcGender {get; init;}
}
Validation happens, then it's mapped if valid:
class Request
{
public required UserTypeTest UserType {get; init;}
}
We use currently have manual mapping to internal types, but ideally custom enum handling in things like mapperly or other cases of using an auto mapper someone could make use of these methods going from RequestDto to Request
VERY Bad implementation
I won't pretend to even have suggestions on how this would be implemented properly or efficiently, but this is a rough version of what I use now:
internal class Program
{
static void Main(string[] args)
{
var emValue = UserTypeTest.Women.ToValueStringFast();
var canParse = EnumExtensions.TryParse<UserTypeTest>(emValue, out var back);
Console.WriteLine($"CAN PARSE: {canParse} PARSED: {emValue}; BACK: {back}");
var canParse2 = EnumExtensions.TryParse<UserTypeTest>("None", out var back2);
Console.WriteLine($"CAN PARSE: {canParse2} PARSED: BACK2: {back2}");
}
}
// bad implementations
static class EnumExtensions
{
public static string ToValueStringFast(this Enum enumVal)
{
var type = enumVal.GetType();
var memInfo = type.GetMember(enumVal.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(EnumMemberAttribute), inherit: false);
if (attributes.Length == 0)
{
throw new Exception($"EnumMember attribute not found for {enumVal?.ToString()} of {enumVal?.GetType()}");
}
if (((EnumMemberAttribute)attributes[0]).Value == null)
{
throw new Exception($"EnumMember value for {enumVal?.ToString()} of {enumVal?.GetType()} was null. Cannot get as string.");
}
return ((EnumMemberAttribute)attributes[0]).Value!;
}
public static bool TryParse<T>(string? value, out T? val)
where T : Enum
{
var type = typeof(T);
foreach (var field in type.GetFields())
{
EnumMemberAttribute? attribute = Attribute.GetCustomAttribute(field, typeof(EnumMemberAttribute)) as EnumMemberAttribute;
if (attribute != null)
{
if (attribute.Value == value)
{
var emValue = field.GetValue(null);
if (emValue == null)
{
throw new Exception($"Enum member for {value} as {typeof(T)} was null");
}
val = (T)emValue;
return true;
}
}
}
val = default;
return false;
}
}
The text was updated successfully, but these errors were encountered:
So this behaviour is sort of already supported, but it uses the [Display] or [Description] attributes instead. Unfortunately, I think that's actually going to be a problem for your example, where you don't want [Display] to be the serialized value (presumably)🤔 We could add support for [EnumMember] in the same way, but I don't think that will help you in the end given you want both attributes. I'm not sure how to support both without making breaking changes unfortunately...
I can rip out the relevant pieces from here around Display and just add local versions of more specific methods for my use case. I just figured it wouldn't hurt to ask first.
Request
Would it be possible to add support for the
EnumMember
attribute?Use Case
For our use case, we have DTO classes that are mapped from JSON and validated
Validation happens, then it's mapped if valid:
We use currently have manual mapping to internal types, but ideally custom enum handling in things like mapperly or other cases of using an auto mapper someone could make use of these methods going from
RequestDto
toRequest
VERY Bad implementation
I won't pretend to even have suggestions on how this would be implemented properly or efficiently, but this is a rough version of what I use now:
The text was updated successfully, but these errors were encountered: