diff --git a/anbs_cp/SimpleMapper.cs b/anbs_cp/SimpleMapper.cs new file mode 100644 index 0000000..cf949ba --- /dev/null +++ b/anbs_cp/SimpleMapper.cs @@ -0,0 +1,132 @@ +using System.Reflection; + +namespace anbs_cp; + +/// +/// Класс перевода одинаковых свойств из класса TF в класс T. +/// Оригинальные автор(-ы): keenthinker и Avtandil Kavrelishvili. +/// Улучшения: А. Н. Бабаев +/// URL: https://stackoverflow.com/questions/20410234/how-to-automatically-map-the-values-between-instances-of-two-different-classes-i +/// +public static class SimpleMapper +{ + /// + /// Перевод одинаковых свойств из класса F в класс TT. + /// + /// Экземпляр класса F + /// Ссылка на экземпляр класса T + /// Тип сопоставления + /// Список параметров для сопоставления + /// Класс-родитель + /// Класс-приёмник + public static void MapEx (TF from, ref T to, MapMode mode, List list) + { + //Копирую поля + Type typeOfA = typeof(TF); + Type typeOfB = typeof(T); + foreach (FieldInfo fieldOfA in typeOfA.GetFields()) + { + //Проверяем выполнение условия и прерываем, если не выполняется + if (CheckCondition(fieldOfA.Name, fieldOfA.GetValue(from), mode, list)) + continue; + + //Получаем FieldInfo для b по имени поля a + FieldInfo? fieldOfB = typeOfB.GetField(fieldOfA.Name); + + //Присваиваю поля типа B значение поля типа A + fieldOfB?.SetValue(to, fieldOfA.GetValue(from)); + } + + //Копирую свойства + foreach (PropertyInfo propertyOfA in typeOfA.GetProperties()) + { + //Проверяем выполнение условия и прерываем, если не выполняется + if (CheckCondition(propertyOfA.Name, propertyOfA.GetValue(from), mode, list)) + continue; + + //Получаем PropertyInfo для b по имени свойства a + PropertyInfo? propertyOfB = typeOfB.GetProperty(propertyOfA.Name); + //Присваиваю свойству типа B значение свойства типа A + propertyOfB?.SetValue(to, propertyOfA.GetValue(from)); + } + } + + /// + /// Перевод одинаковых свойств из класса F в класс TT (режим "сопоставление всех параметров"). + /// + /// Параметр класса F + /// Класс-родитель + /// Класс-приёмник + /// Элемент класса T + public static T Map (TF from) + { + //Создаю элемент + // ReSharper disable once NullableWarningSuppressionIsUsed + T result = (T)Activator.CreateInstance(typeof(T))!; + //Сопоставляю по принципу "сопоставление всех параметров" + MapEx(from, ref result, MapMode.MapFull, new()); + //Вывожу в результат + return result; + } + + /// + /// Проверка выполнения условия + /// + /// Имя элемента + /// Значение элемента + /// Режим проверки + /// Список игнорирования/добавления + /// + private static bool CheckCondition (string itemName, object? itemValue, MapMode mode, ICollection list) + { + //Если режим "Только список" и поля нет в списке, + //либо режим "Только не в списке" и поле есть в списке + //или режим "Только не пустые" и значение поля пустое, + //или режим "Только не по умолчанию" и значение по умолчанию + //то пропускаем + bool result = + mode switch { + MapMode.MapFull => true, + MapMode.MapNotNull => itemValue != null, + MapMode.MapByList => list.Contains(itemName), + MapMode.MapIgnoreList => !list.Contains(itemName), + MapMode.MapNotDefault => itemValue != default, + MapMode.MapNotNullOrDefault => itemValue != null || itemValue != default, + _ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null) + }; + + //Возвращаем результат + return result; + } + + /// + /// Перечисление типов сопоставления + /// + public enum MapMode + { + /// + /// Сопоставление всех параметров + /// + MapFull = 0, + /// + /// Сопоставление не пустых параметров + /// + MapNotNull = 1, + /// + /// Сопоставление по списку + /// + MapByList = 2, + /// + /// Сопоставление исключая список + /// + MapIgnoreList = 3, + /// + /// Сопоставление параметров, которые не равны значению по умолчанию + /// + MapNotDefault = 4, + /// + /// Сопоставление не пустых параметров, которые не равны значению по умолчанию (NotNull и NotDefault одновременно) + /// + MapNotNullOrDefault = 5, + } +} \ No newline at end of file diff --git a/anbs_cp/anbs_cp.csproj b/anbs_cp/anbs_cp.csproj index bb30827..0e403bf 100644 --- a/anbs_cp/anbs_cp.csproj +++ b/anbs_cp/anbs_cp.csproj @@ -2,7 +2,7 @@ net6.0 - 1.2021.1215 + 1.2022.223 Alexander Babaev ANB Software Components Pack Library of some useful functions in C# language. @@ -15,8 +15,8 @@ False https://github.com/GoodBoyAlex/anbsoftware_componentspack https://github.com/GoodBoyAlex/anbsoftware_componentspack - 1.2021.1215 - 1.2021.1215 + 1.2022.0223 + 1.2022.223 ANBSoftware.ComponentsPack MIT 6.0 @@ -33,7 +33,7 @@ - +