20240211
This commit is contained in:
parent
341b409264
commit
a586c5a0f9
@ -1,5 +1,6 @@
|
||||
using System.Collections;
|
||||
|
||||
using anbs_cp.Interfaces;
|
||||
using anbs_cp.Structs;
|
||||
|
||||
namespace anbs_cp.Classes;
|
||||
@ -10,7 +11,7 @@ namespace anbs_cp.Classes;
|
||||
/// <typeparam name="TK">Тип ключа</typeparam>
|
||||
/// <typeparam name="TV">Тип значения</typeparam>
|
||||
// ReSharper disable once ClassCanBeSealed.Global
|
||||
public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>
|
||||
public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>, ISerializable
|
||||
{
|
||||
/// <summary>
|
||||
/// Хранение значений
|
||||
@ -171,4 +172,42 @@ public class KeyValueList<TK, TV>: IEnumerable<KeyValue<TK, TV>>
|
||||
/// <returns><see cref="IEnumerator"/></returns>
|
||||
IEnumerator IEnumerable.GetEnumerator () => GetEnumerator();
|
||||
#endregion
|
||||
|
||||
#region Реализация интерфейса ISerializable
|
||||
/// <inheritdoc />
|
||||
public string Serialize ()
|
||||
{
|
||||
// Создаю результат
|
||||
List<string> result = [];
|
||||
|
||||
// Добавляю сериализованные значения
|
||||
result.AddRange(_list.Select(static item => item.Serialize()));
|
||||
|
||||
// Вывожу результат
|
||||
return new SysTextSerializer().Serialize(result);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Deserialize (string json)
|
||||
{
|
||||
// Создаю результат
|
||||
List<string> result = new SysTextSerializer().Deserialize<List<string>>(json) ?? [];
|
||||
|
||||
// Очищаю список
|
||||
_list.Clear();
|
||||
|
||||
// Пробегаю все значения
|
||||
foreach (string itemString in result)
|
||||
{
|
||||
// - создаю новое значение
|
||||
KeyValue<TK, TV> item = new();
|
||||
|
||||
// - десериализую в него элемента
|
||||
item.Deserialize(itemString);
|
||||
|
||||
// - добавляю получившееся в список
|
||||
_list.Add(item);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
17
anbs_cp/Enums/ESerializeExceptionAction.cs
Normal file
17
anbs_cp/Enums/ESerializeExceptionAction.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace anbs_cp.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// Действие, которое привело к ошибке сериализации
|
||||
/// </summary>
|
||||
public enum ESerializeExceptionAction
|
||||
{
|
||||
/// <summary>
|
||||
/// Сериализация
|
||||
/// </summary>
|
||||
Serialize = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Десериализация
|
||||
/// </summary>
|
||||
Deserialize = 1
|
||||
}
|
28
anbs_cp/Exceptions/SerializeException.cs
Normal file
28
anbs_cp/Exceptions/SerializeException.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using anbs_cp.Enums;
|
||||
|
||||
namespace anbs_cp.Exceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Ошибка (де)сериализации
|
||||
/// </summary>
|
||||
/// <param name="action">Действие сериализатора, приведшее к ошибке</param>
|
||||
/// <param name="objectJson">Объект сериализации при сериализации или строка json при десериализации</param>
|
||||
/// <param name="message">Сообщение пользователю</param>
|
||||
public sealed class SerializeException (ESerializeExceptionAction action, string? objectJson, string? message = null)
|
||||
: Exception(message)
|
||||
{
|
||||
/// <summary>
|
||||
/// Действие сериализатора, приведшее к ошибке
|
||||
/// </summary>
|
||||
public ESerializeExceptionAction Action => action;
|
||||
|
||||
/// <summary>
|
||||
/// Объект сериализации (при action == ESerializeExceptionAction.Serialize)
|
||||
/// </summary>
|
||||
public string? Object => action == ESerializeExceptionAction.Serialize ? objectJson : null;
|
||||
|
||||
/// <summary>
|
||||
/// Строка json при десериализации
|
||||
/// </summary>
|
||||
public string? Json => action == ESerializeExceptionAction.Deserialize ? objectJson : null;
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
namespace anbs_cp.Interfaces;
|
||||
using anbs_cp.Exceptions;
|
||||
|
||||
namespace anbs_cp.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс для сериализации объектов
|
||||
@ -9,11 +11,13 @@ public interface ISerializable
|
||||
/// Сериализовать элемент в формат json
|
||||
/// </summary>
|
||||
/// <returns>Строка в формате json</returns>
|
||||
/// <exception cref="SerializeException">Ошибка при сериализации</exception>
|
||||
string Serialize();
|
||||
|
||||
/// <summary>
|
||||
/// Восстановить элемент из формата json
|
||||
/// </summary>
|
||||
/// <param name="json">Строка в формате json</param>
|
||||
/// <exception cref="SerializeException">Ошибка при десериализации</exception>
|
||||
void Deserialize(string json);
|
||||
}
|
@ -1,23 +1,29 @@
|
||||
namespace anbs_cp.Structs;
|
||||
using anbs_cp.Classes;
|
||||
using anbs_cp.Enums;
|
||||
using anbs_cp.Exceptions;
|
||||
|
||||
using ISerializable = anbs_cp.Interfaces.ISerializable;
|
||||
|
||||
namespace anbs_cp.Structs;
|
||||
|
||||
/// <summary>
|
||||
/// Пара ключ-значение
|
||||
/// Пара ключ-значение
|
||||
/// </summary>
|
||||
/// <typeparam name="TK">Тип ключа</typeparam>
|
||||
/// <typeparam name="TV">Тип значения</typeparam>
|
||||
/// <param name="key">Ключ</param>
|
||||
/// <param name="value">Значение</param>
|
||||
public struct KeyValue<TK, TV>(TK key, TV? value)
|
||||
public struct KeyValue<TK, TV> (TK key, TV? value): ISerializable
|
||||
{
|
||||
#region Свойства
|
||||
|
||||
/// <summary>
|
||||
/// Ключ
|
||||
/// Ключ
|
||||
/// </summary>
|
||||
public TK Key { get; set; } = key;
|
||||
|
||||
/// <summary>
|
||||
/// Значение
|
||||
/// Значение
|
||||
/// </summary>
|
||||
public TV? Value { get; set; } = value;
|
||||
|
||||
@ -26,10 +32,56 @@ public struct KeyValue<TK, TV>(TK key, TV? value)
|
||||
#region Методы
|
||||
|
||||
/// <summary>
|
||||
/// Получает ключ-значение по умолчанию
|
||||
/// Получает ключ-значение по умолчанию
|
||||
/// </summary>
|
||||
/// <returns>Ключ-значение по умолчанию</returns>
|
||||
public static KeyValue<TK, TV> GetDefault() => new();
|
||||
public static KeyValue<TK, TV> GetDefault () => new();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Реализация интерфейса ISerializable
|
||||
/// <inheritdoc />
|
||||
public readonly string Serialize ()
|
||||
{
|
||||
// Получаю serialized-значение ключа
|
||||
string keySerialized = new SysTextSerializer().Serialize(Key);
|
||||
|
||||
// Исключаю из этого значения = (заменяя на %EQ%)
|
||||
keySerialized = keySerialized.Replace("=", "%EQ%");
|
||||
|
||||
// Получаю serialized-значение значения
|
||||
string valueSerialized = new SysTextSerializer().Serialize(Value);
|
||||
|
||||
// Исключаю из этого значения = (заменяя на %EQ%)
|
||||
valueSerialized = valueSerialized.Replace("=", "%EQ%");
|
||||
|
||||
// Вывожу результат
|
||||
return $"{keySerialized}={valueSerialized}";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Deserialize (string json)
|
||||
{
|
||||
// Разделяю сериализованную строку вида КЛЮЧ=ЗНАЧЕНИЕ на ключ и значение
|
||||
string[] splited = json.Split('=');
|
||||
|
||||
// Проверяю количество частей (должно быть 2)
|
||||
if (splited.Length != 2)
|
||||
throw new SerializeException(ESerializeExceptionAction.Deserialize, json,
|
||||
"Неверное количество частей! Наверное, лишнее =?");
|
||||
|
||||
// Получаю сериализованное представление ключа
|
||||
string keySerialized = splited[0].Replace("%EQ%", "=");
|
||||
|
||||
// Получаю сериализованное представление значения
|
||||
string valueSerialized = splited[1].Replace("%EQ%", "=");
|
||||
|
||||
// Десериализую ключ
|
||||
Key = (new SysTextSerializer().Deserialize<TK>(keySerialized) ?? default(TK))!;
|
||||
|
||||
// Десериализую значение
|
||||
Value = new SysTextSerializer().Deserialize<TV>(valueSerialized);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Version>2024.2.6.1</Version>
|
||||
<Version>2024.2.11</Version>
|
||||
<Authors>Александр Бабаев</Authors>
|
||||
<Product>Набор компонентов ANB Software</Product>
|
||||
<Description>Библиотека полезных методов языка C#</Description>
|
||||
@ -22,6 +22,7 @@
|
||||
<AnalysisLevel>6.0</AnalysisLevel>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<Title>Библиотека полезных методов и классов от ANB</Title>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
@ -23,6 +23,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0421_043E_0437_0434_0430_0451_043C/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0432_0432_0435_0434_0451_043D/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0432_0438_0434_0435_043E_043A_0430_0440_0442_0435/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_0438/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_044F/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0448_0438_0444_0440_043E_0432_0430_043D_0438_044F/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0434_0435_0448_0438_0444_0440_043E_0432_0447_0438_043A/@EntryIndexedValue">True</s:Boolean>
|
||||
@ -31,9 +32,12 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043A_0440_0438_043F_0442_043E_0433_0440_0430_0444/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043F_043E_0434_0447_0451_0440_043A_043D_0443_0442_044B_0439/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_043F_0443_0442_0451_043C/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_0430_0442_043E_0440_0430/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_0438/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_0430_0446_0438_044F/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_043D_043D_043E_0433_043E/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_043D_043D_043E_0435/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0435_0440_0438_0430_043B_0438_0437_043E_0432_0430_043D_043D_0443_044E/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0447_0451_0442/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0441_0447_0451_0442_0447_0438_043A/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0445_044D_0448_0430/@EntryIndexedValue">True</s:Boolean>
|
||||
|
Loading…
x
Reference in New Issue
Block a user