From 8c5dca14919b2b74cc0db549e2beb764647a07ca Mon Sep 17 00:00:00 2001 From: FrigaT Date: Thu, 23 Apr 2026 17:16:18 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BF=D0=B0=D1=80=D1=81=D0=B8=D0=BD=D0=B3=20EnumMembe?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- YandexMusic.API/Extensions/EnumHelper.cs | 49 +++++++++++++++++++ .../Landing/Entity/YLandingEntityConverter.cs | 4 +- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 YandexMusic.API/Extensions/EnumHelper.cs diff --git a/YandexMusic.API/Extensions/EnumHelper.cs b/YandexMusic.API/Extensions/EnumHelper.cs new file mode 100644 index 0000000..95624f3 --- /dev/null +++ b/YandexMusic.API/Extensions/EnumHelper.cs @@ -0,0 +1,49 @@ +using System.Collections.Concurrent; +using System.Reflection; +using System.Runtime.Serialization; + +namespace YandexMusic.API.Extensions; + +public static class EnumHelper +{ + private static readonly ConcurrentDictionary> _enumMaps = new(); + + /// + /// Пытается преобразовать строковое значение в enum с учётом атрибутов [EnumMember]. + /// + /// Тип enum + /// Строковое значение из JSON или другого источника + /// Учитывать регистр (по умолчанию true) + /// Результат преобразования, если успешно, иначе default + /// true если преобразование удалось, иначе false + public static bool TryEnumFromMemberValue(string memberValue, bool ignoreCase, out T result) where T : struct, Enum + { + result = default; + if (string.IsNullOrEmpty(memberValue)) + return false; + + var type = typeof(T); + // Получаем или создаём кэш для данного enum + var map = _enumMaps.GetOrAdd(type, t => + { + var dict = new Dictionary(ignoreCase ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal); + foreach (var field in t.GetFields(BindingFlags.Static | BindingFlags.Public)) + { + var attr = field.GetCustomAttribute(); + var key = attr?.Value ?? field.Name; + dict[key] = field.GetValue(null)!; + } + return dict; + }); + + // Ищем по кэшу + if (map.TryGetValue(memberValue, out var value)) + { + result = (T)value; + return true; + } + + // fallback на обычный Enum.TryParse (без учёта EnumMember) + return Enum.TryParse(memberValue, ignoreCase, out result); + } +} \ No newline at end of file diff --git a/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs b/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs index 2f1e0e1..d672621 100644 --- a/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs +++ b/YandexMusic.API/Models/Landing/Entity/YLandingEntityConverter.cs @@ -1,5 +1,6 @@ using System.Text.Json; using System.Text.Json.Serialization; +using YandexMusic.API.Extensions; using YandexMusic.API.Models.Landing.Entity.Entities; namespace YandexMusic.API.Models.Landing.Entity; @@ -26,7 +27,8 @@ public class YLandingEntityConverter : JsonConverter> var typeProp = root.GetProperty("type"); var typeStr = typeProp.GetString(); - if (!Enum.TryParse(typeStr, true, out var entityType)) + + if (!EnumHelper.TryEnumFromMemberValue(typeStr, true, out var entityType)) throw new JsonException($"Неизвестный тип сущности: {typeStr}"); YLandingEntity? entity = null;