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>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>1.2021.1215</Version>
|
<Version>1.2022.223</Version>
|
||||||
<Authors>Alexander Babaev</Authors>
|
<Authors>Alexander Babaev</Authors>
|
||||||
<Product>ANB Software Components Pack</Product>
|
<Product>ANB Software Components Pack</Product>
|
||||||
<Description>Library of some useful functions in C# language.</Description>
|
<Description>Library of some useful functions in C# language.</Description>
|
||||||
@ -15,8 +15,8 @@
|
|||||||
<SignAssembly>False</SignAssembly>
|
<SignAssembly>False</SignAssembly>
|
||||||
<PackageProjectUrl>https://github.com/GoodBoyAlex/anbsoftware_componentspack</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/GoodBoyAlex/anbsoftware_componentspack</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/GoodBoyAlex/anbsoftware_componentspack</RepositoryUrl>
|
<RepositoryUrl>https://github.com/GoodBoyAlex/anbsoftware_componentspack</RepositoryUrl>
|
||||||
<AssemblyVersion>1.2021.1215</AssemblyVersion>
|
<AssemblyVersion>1.2022.0223</AssemblyVersion>
|
||||||
<FileVersion>1.2021.1215</FileVersion>
|
<FileVersion>1.2022.223</FileVersion>
|
||||||
<PackageId>ANBSoftware.ComponentsPack</PackageId>
|
<PackageId>ANBSoftware.ComponentsPack</PackageId>
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<AnalysisLevel>6.0</AnalysisLevel>
|
<AnalysisLevel>6.0</AnalysisLevel>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop" Version="17.0.31902.203" />
|
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop" Version="17.1.32210.191" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user