20220223
This commit is contained in:
parent
e08aeca7aa
commit
bff4cb735c
132
anbs_cp/SimpleMapper.cs
Normal file
132
anbs_cp/SimpleMapper.cs
Normal file
@ -0,0 +1,132 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace anbs_cp;
|
||||
|
||||
/// <summary>
|
||||
/// Класс перевода одинаковых свойств из класса TF в класс T.
|
||||
/// Оригинальные автор(-ы): keenthinker и Avtandil Kavrelishvili.
|
||||
/// Улучшения: А. Н. Бабаев
|
||||
/// URL: https://stackoverflow.com/questions/20410234/how-to-automatically-map-the-values-between-instances-of-two-different-classes-i
|
||||
/// </summary>
|
||||
public static class SimpleMapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Перевод одинаковых свойств из класса F в класс TT.
|
||||
/// </summary>
|
||||
/// <param name="from">Экземпляр класса F</param>
|
||||
/// <param name="to">Ссылка на экземпляр класса T</param>
|
||||
/// <param name="mode">Тип сопоставления</param>
|
||||
/// <param name="list">Список параметров для сопоставления</param>
|
||||
/// <typeparam name="TF">Класс-родитель</typeparam>
|
||||
/// <typeparam name="T">Класс-приёмник</typeparam>
|
||||
public static void MapEx<TF, T> (TF from, ref T to, MapMode mode, List<string> 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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Перевод одинаковых свойств из класса F в класс TT (режим "сопоставление всех параметров").
|
||||
/// </summary>
|
||||
/// <param name="from">Параметр класса F</param>
|
||||
/// <typeparam name="TF">Класс-родитель</typeparam>
|
||||
/// <typeparam name="T">Класс-приёмник</typeparam>
|
||||
/// <returns>Элемент класса T</returns>
|
||||
public static T Map<TF, T> (TF from)
|
||||
{
|
||||
//Создаю элемент
|
||||
// ReSharper disable once NullableWarningSuppressionIsUsed
|
||||
T result = (T)Activator.CreateInstance(typeof(T))!;
|
||||
//Сопоставляю по принципу "сопоставление всех параметров"
|
||||
MapEx(from, ref result, MapMode.MapFull, new());
|
||||
//Вывожу в результат
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверка выполнения условия
|
||||
/// </summary>
|
||||
/// <param name="itemName">Имя элемента</param>
|
||||
/// <param name="itemValue">Значение элемента</param>
|
||||
/// <param name="mode">Режим проверки</param>
|
||||
/// <param name="list">Список игнорирования/добавления</param>
|
||||
/// <returns></returns>
|
||||
private static bool CheckCondition (string itemName, object? itemValue, MapMode mode, ICollection<string> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Перечисление типов сопоставления
|
||||
/// </summary>
|
||||
public enum MapMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Сопоставление всех параметров
|
||||
/// </summary>
|
||||
MapFull = 0,
|
||||
/// <summary>
|
||||
/// Сопоставление не пустых параметров
|
||||
/// </summary>
|
||||
MapNotNull = 1,
|
||||
/// <summary>
|
||||
/// Сопоставление по списку
|
||||
/// </summary>
|
||||
MapByList = 2,
|
||||
/// <summary>
|
||||
/// Сопоставление исключая список
|
||||
/// </summary>
|
||||
MapIgnoreList = 3,
|
||||
/// <summary>
|
||||
/// Сопоставление параметров, которые не равны значению по умолчанию
|
||||
/// </summary>
|
||||
MapNotDefault = 4,
|
||||
/// <summary>
|
||||
/// Сопоставление не пустых параметров, которые не равны значению по умолчанию (NotNull и NotDefault одновременно)
|
||||
/// </summary>
|
||||
MapNotNullOrDefault = 5,
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Version>1.2021.1215</Version>
|
||||
<Version>1.2022.223</Version>
|
||||
<Authors>Alexander Babaev</Authors>
|
||||
<Product>ANB Software Components Pack</Product>
|
||||
<Description>Library of some useful functions in C# language.</Description>
|
||||
@ -15,8 +15,8 @@
|
||||
<SignAssembly>False</SignAssembly>
|
||||
<PackageProjectUrl>https://github.com/GoodBoyAlex/anbsoftware_componentspack</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/GoodBoyAlex/anbsoftware_componentspack</RepositoryUrl>
|
||||
<AssemblyVersion>1.2021.1215</AssemblyVersion>
|
||||
<FileVersion>1.2021.1215</FileVersion>
|
||||
<AssemblyVersion>1.2022.0223</AssemblyVersion>
|
||||
<FileVersion>1.2022.223</FileVersion>
|
||||
<PackageId>ANBSoftware.ComponentsPack</PackageId>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<AnalysisLevel>6.0</AnalysisLevel>
|
||||
@ -33,7 +33,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop" Version="17.0.31902.203" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop" Version="17.1.32210.191" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
Loading…
x
Reference in New Issue
Block a user