san40_u5an40.ExtraLib
5.4.0
dotnet add package san40_u5an40.ExtraLib --version 5.4.0
NuGet\Install-Package san40_u5an40.ExtraLib -Version 5.4.0
<PackageReference Include="san40_u5an40.ExtraLib" Version="5.4.0" />
<PackageVersion Include="san40_u5an40.ExtraLib" Version="5.4.0" />
<PackageReference Include="san40_u5an40.ExtraLib" />
paket add san40_u5an40.ExtraLib --version 5.4.0
#r "nuget: san40_u5an40.ExtraLib, 5.4.0"
#:package san40_u5an40.ExtraLib@5.4.0
#addin nuget:?package=san40_u5an40.ExtraLib&version=5.4.0
#tool nuget:?package=san40_u5an40.ExtraLib&version=5.4.0
san40_u5an40.ExtraLib
В данном NuGet-пакете представлена библиотека классов, расширяющая стандартные возможности программирования. В ней представлены паттерны, полезные как при процедурном стиле программирования, так и при объектно-ориентированном.
Оглавление:
Ядро (san40_u5an40.ExtraLib.Core):
Паттерны (san40_u5an40.ExtraLib.Patterns):
Валидация (san40_u5an40.ExtraLib.Validation):
Обработка данных (san40_u5an40.ExtraLib.Data):
Ввод-вывод (san40_u5an40.ExtraLib.IO):
Рефлексия (san40_u5an40.ExtraLib.Reflection):
Bytes
Назначение
Статический класс для конвертирования байтов.
Структура
Статические методы:
ToSize(Long)— Переводит полученное количество байт в набор гигабайт, мегабайт, килобайт и байт, представленный структуройSize.ToGb(Long)— Переводит байты в гигабайты с математическим округлением.ToMb(Long)— Переводит байты в мегабайты с математическим округлением.ToKb(Long)— Переводит байты в килобайты с математическим округлением.
Свойства структуры Size:
long GByte— Количество гигабайт.long MByte— Количество мегабайт.long KByte— Количество килобайт.long Byte— Количество оставшихся байт.
Примеры кода
var drives = DriveInfo.GetDrives();
foreach (var drive in drives)
{
var str = new StringBuilder()
.AppendLine("Имя диска: " + drive.Name)
.AppendLine("Метка диска: " + drive.VolumeLabel)
.AppendLine("Общий размер: " + Bytes.ToSize(drive.TotalSize));
Console.WriteLine(str);
}
// Вывод:
//
// Имя диска: C:\
// Метка диска:
// Общий размер: 100 Гбайт, 207 Мбайт, 1008 Кбайт 0 байт
//
// Имя диска: D:\
// Метка диска: Data
// Общий размер: 171 Гбайт, 115 Мбайт, 1020 Кбайт 0 байт
Comparator
Назначение
Статический класс, который возвращает объект IComparer позволяющий сравнивать пользовательские типы по указанному параметру. Полезен при работе с Array.
Структура
Статические методы:
GetComparator<TSource, TKey>— Возвращает созданный объект для сравнения по переданной лямбде. Первым Generic-параметром указывается элемент коллекции, вторым возвращаемый тип данных.
Примеры кода
Array.Sort(array, Comparator.GetComparator<User, string>(p => p.Name));
// Сортировка массива объектов "User" по имени
// string - т.к. этим типом представлено свойство Name
DefaultConstants
Назначение
Дополнительные константы для примитивов.
Структура
string.NotEmpty— Непустая строкаsomething.int.PositiveNumber— Положительное число1.int.Zero— Содержит ноль (более явная формаdefault).int.NegativeNumber— Отрицательное число-1.int.RandomValue— Случайное число.int.RandomPositiveValue— Случайное положительное число.int.RandomNegativeValue— Случайное отрицательное число.int.Random(int max)— Случайное число от 0 до указанного значения.int.Random(int min, int max)— Случайное число в указанном диапазоне.
Примеры кода
Counter counter = new(value: int.RandomPositiveValue, name: string.NotEmpty);
IEnumerableExtensions
Назначение
Статический класс с методами расширения для перебираемых коллекций.
Структура
Методы расширения:
IsSorted— Проверяет отсортированность по возрастанию.IsSortedDescending— Проверяет отсортированность по убыванию.Have— Проверяет наличие в коллекции указанного количества элементов. Более оптимален, чем проверки с полным перебором коллекции методомCount.
Примеры кода
IsSorted:
List<int> numbers = new() { 1, 2, 3, 4, 10 };
bool isSorted = numbers.IsSorted(); // true
Have:
if (!collection.Have(2))
return true;
ObjectExtensions
Назначение
Статический класс с методами расширения для объектов.
Структура
Методы расширения:
TryCast— Осуществляет попытку приведения типа, возвращая логическое значение об успехе, и записывающее сам объект в out-параметр. При необходимости вторым out-параметром возвращает сообщение об ошибке приведения типа.IsNull— Проверяет значение на равенствоnullи возвращает результат проверки.IsNotNull— Проверяет значение на не равенствоnullи возвращает результат проверки.
Примеры кода
TryCast:
object obj = 10;
bool isCasted = obj.TryCast(out string? str, out string? castingError);
if (!isCasted)
Console.WriteLine(castingError); // Specified value is not a String
IsNull:
if (parameters.Any(p => p.IsNull()))
throw new AttributeParametersException(parameters, "Attribute values cannot have null values");
StringExtensions
Назначение
Статический класс с методами расширения для строк.
Структура
Методы расширения:
Reduce— Сокращает строку до указанной длины, возвращая получившееся значениеMessageи остаток длиныRemainder.ReplaceWhileContain— Заменяет старое значение на новое, пока в тексте содержится старое значение (удобно для удаления повторяющихся символов).TryFormat— Осуществляет попытку форматировать строку с указанными переменными, возвращая логическое значение об успешности, и саму форматированную строку при помощи out-параметра.IsValidForInternalization— Проверка валидности строки на предмет интернирования указанного количества переменных.
Примеры кода
Reduce:
var result = "Очень длинная строка!".Reduce(9);
Console.WriteLine($"Получившаяся строка: {result.Message}; Остаток длины: {result.Remainder}");
// Получившаяся строка: Очень ...; Остаток длины: 0
result = "По-прежнему очень длинная строка!".Reduce(50);
Console.WriteLine($"Получившаяся строка: {result.Message}; Остаток длины: {result.Remainder}");
// Получившаяся строка: По - прежнему очень длинная строка!; Остаток длины: 17
ReplaceWhileContain:
string text = "Строка, где очень много лишних пробелов";
string textWithoutDoubleSpace = text.ReplaceWhileContain(" ", " ");
TryFormat:
string str = "{0} {1}";
bool isSuccessFormat = str.TryFormat(out string formatted, 10, 12);
IsValidForInternalization:
string str = "{0} {1}";
var validationResult = str.IsValidForInternalization(2);
Readyable
Назначение
Потокобезопасный объект, проверяемый на готовность. Удобен при необходимости отложено инициализировать out-параметры.
Структура
Generic-параметр:
TValue— Тип хранимого значения.
Свойства:
Name— Имя объекта.Value— Значение объекта.State— Состояние объекта, представленное перечислениемReadyableState:NeverBeReady— Объект, который никогда не будет готов к использованию.Waiting— Объект, ожидающий готовности.Ready— Объект, готовый к использованию.
IsInitialized— Логическое значение, отражающее инициализированы ли данные.IsWaiting— Логическое значение, отражающее находится ли объект в режиме ожидания.IsReady— Логическое значение, отражающее готов ли объект.IsNeverBeReady— Логическое значение, отражающее находится ли объект в состоянии, в котором уже никогда не будет готов.
Методы:
ThrowIfNotInitialized— Выбрасывает исключение, если значение объекта не инициализировано.ThrowIfNotWaiting— Выбрасывает исключение, если объект не ожидает значение.ThrowIfNotReady— Выбрасывает исключение, если объект не находится в состоянии готовности.ToReady(Только явное использование) — Приводит объект в состояние готовности. Можно указать итоговое значение объекта.ToNeverBeReady(Только явное использование) — Приводит объект в состояние, в котором он уже не будет готов никогда.
Ассоциированное с этим классом исключение ReadyableException:
Message— Сообщение об ошибке.Name— Имя объекта, проверяемого на готовность.State— Состояние объекта, связанного с ошибкой.
Соглашение об использовании:
Подразумевается, что после создание этого объекта он будет либо инициализирован и приведён в состояние готовности, либо приведён в состояние, когда он никогда не будет готов.
Если запросить его значение, когда он не находится в состоянии готовности, возникнет исключение. Как и при попытке его привести в состояние готовности, если его значение не было проинициализированно.
Примеры кода
При успешном выполнении какой-то операции, например:
// Внутри какого-то метода
((IReadyable<int>)readyable).ToReady(3); // Явное использование для небольшой защиты от лишнего вмешательства
// Где-нибудь снаружи
int value = readyable.IsReady ? readyable.Value : default;
При какой-нибудь ошибке:
if (somethingBad)
((IReadyable<int>)readyable).ToNeverBeReady();
Result
Назначение
Класс, хранящий сведенья о результате работы метода.
Структура
Статические методы для создания результата:
CreateSuccess— Создаёт сведенья об успешном результате (Есть интеграция сReadyable).CreateFailure— Создаёт сведенья о невалидном результате (Есть интеграция сReadyable).
Свойства результата:
IsValid— Валидность результата.Value— Данные валидного результата.Error— Данные невалидного результата.
Обычные методы:
ExecuteAndExitIfNotValid— Выполняет действие надResult.Errorи завершает работу приложения.
Generic-параметры:
TSuccess(первый параметр) — Тип данных, которым будет представлено свойствоValue.TFailure(второй параметр) — Тип данных, которым представлено свойствоError.
Примеры кода
Стандартное использование:
var success = Result<string, string>.CreateSuccess("Успешный успех!");
var failure = Result<string, string>.CreateFailure("Потеря потерь!");
string successMessage = success.IsValid ? success.Value : success.Error;
string failureMessage = failure.IsValid ? failure.Value : failure.Error;
Console.WriteLine(successMessage + '\n' + failureMessage);
При частом использовании одинакового набора Generic-параметров можно использовать псевдонимы:
using StringResult = san40_u5an40.ExtraLib.Broad.Result<string, string>;
var success = StringResult.CreateSuccess("Успешный успех!");
И конечно же допустимо использовать различные пользовательские типы в качестве Generic-параметров:
var success = Result<SuccessInfo, FailureInfo>.CreateSuccess(new SuccessInfo("Вася", 25));
string message =
success.IsValid ?
success.Value.Name + ' ' + success.Value.Age :
success.Error.Message;
Console.WriteLine(message);
record SuccessInfo(string Name, int Age);
record FailureInfo(string Message, int ErrorCode);
ExecuteAndExitIfNotValid:
var result = Result<string, string>.CreateFailure("FAIL!!!!");
result.ExecuteAndExitIfNotValid(Console.WriteLine);
Console.WriteLine("Если бы ты не упал, ты бы жил");
// Вывод:
// FAIL!!!
Интеграция с Readyable
Методы CreateSuccess и CreateFailure имеют перегрузки со вторым Readyable параметром, который устанавливает состояние объекта в то или иное значение в зависимости от метода:
CreateSuccess— ИнициализируетReadyable.ValueсвоимResult.Valueи устанавливает состояниеReady.CreateFailure— Устанавливает состояниеReadyableвNeverBeReady.
Допустимо передавать в параметр только те объекты, которые находятся в состоянии Wait. Иные попытки приведут к исключению ReadyableException.
Readyable<string> readyable = new();
Result<string,string>.CreateSuccess("Какое-то значение!", readyable);
// Теперь readyable.Value == "Какое-то значение!", а readyable.State == ReadyableState.Ready;
Chain and AsyncChain
Назначение
Классы для создания функциональных цепочек. При их запуске указанные методы начинают до конца исполняться, передавая указанные данные. Если на каком-то этапе возникнет невалидный результат, вернётся соответствующая информация об ошибке.
Примеры кода
Обычная цепочка:
var chainResult = new Chain<string[], object, string>(args) // string[] - Тип входных данных, object - Выходных, string - Ошибка, args - Сами входные данные
.AddMethod<string[], ArgumentsInfo>(HandleArguments) // Получил string[], вернул Result<ArgumentsInfo, string>
.AddMethod<ArgumentsInfo, ContentInfo>(GetContents) // Получил ArgumentsInfo, вернул Result<ContentInfo, string>
.AddMethod<ContentInfo, WriterInfo>(GetOutputFileInfo) // Получил ContentInfo, вернул Result<WriterInfo, string>
.AddMethod<WriterInfo, object>(WriteContents) // Получил WriterInfo, вернул Result<object, string>
.Execute(); // Возвращает Result<object, string> (в данном случае object - заглушка)
if (!chainResult.IsValid)
{
Console.WriteLine(chainResult.Error);
return;
}
Console.WriteLine("Файл с оглавлением успешно создан!");
Асинхронная:
var asyncChainResult = await new AsyncChain<string, int, string>(DOCUMENT_PATH)
.AddMethod<string, int>(GetNumberFromDocumentAsync) // Получил string, вернул Task<Result<int, string>>
.AddMethod<int, int>(IncrementNumberAsync) // Получил int, вернул Task<Result<int, string>>
.ExecuteAsync();
AddLoop:
new Chain<string, string, string>(string.NotEmpty)
.AddLoop<string, string>(DoSomethingDelegate, Console.WriteLine, 5);
// Если результат будет не валиден, метод повторится, но не больше 5 раз
// Невалидный результат будет печаться в консоль, в соответствии со вторым переданным делгатом
С проектом, реализованным на базе функциональной цепочки, можно ознакомиться тут. Также более наглядный пример есть в проекте с тестами.
Структура
Создание объекта Chain и AsyncChain:
- Generic-параметры:
TInputData— Тип входных данных в цепочку.TOutputData— Тип выходных данных из цепочки.TError— Тип возвращаемой на каком-либо этапе ошибки.
- Конструктор, где и указывают начальные данные цепочки и токен завершения (в случае AsyncChain).
Методы цепочки:
AddMethod— Добавляет указанные делегат в цепочку (есть поддержкаReadyableout-параметра).TInput— Тип получаемых методом данных.TOutput— Тип возвращаемых методом данных в видеResult<this, Chain.TError>илиTask<Result<this, Chain.TError>>при асинхронных методах.
AddLoop— Добавляет указанные делегат в цепочку, который при невалидном результате будет повторяться не больше заданного количества раз (также есть поддержкаReadyableout-параметра).TInput— Тип получаемых методом данных.TOutput— Тип возвращаемых методом данных в видеResult<this, Chain.TError>илиTask<Result<this, Chain.TError>>при асинхронных методах.
Execute/ExecuteAsync— Выполняет цепочку и возвращаетResult<Chain.TOutputData, Chain.TError>для обычной цепочки иResult<Chain.TOutputData, InvalidAsyncChainResult<Chain.TError>>.
Подробнее про InvalidAsyncChainResult, хранимый в Result.Error у асинхронной цепочки:
Value?— Информация о хранимой ошибке, представлена типомChain.TError.Type— Тип невалидного результата, представленный перечислениемInvalidAsyncChainResultType, имеющим следующие значения:CancellationTokenRequested— Был вызван токен завершения, и его обработала цепочка (если он обрабатывается внутри метода, то тип ошибки будет другой).NotValidMethodResult— Один из методов вернул невалидный результат.
Соглашения об использовании:
- Тип входных данных первого метода цепочки и тип выходных данных последнего метода цепочки должны совпадать с типами начальных и выходных данных самой цепочки (иначе возникнет исключение).
- Методы цепочки должны возвращать
Result<TOutput, TError>, однако следующий метод принимает параметром толькоTOutput. Информация о валидности и сведенья об ошибке нужны для понимание самой цепочкой корректности выполнения операций.
Использование out-параметра в AddMethod
С помощью объекта Readyable можно получать промежуточные результаты, передаваемых цепочкой данных:
var incrementResult = new Chain<string, string, string>(START_VALUE)
.AddMethod<string, int>(ConvertStringIntoInt)
.AddMethod<int, int>(Increment, out Readyable<int> readyable) // Сохранит промежуточный результат
.AddMethod<int, string>(ConvertIntIntoString)
.Execute();
Counter
Назначение
Класс, предназначенный для создания счётчиков.
Структура
Свойства:
Value— Значение счётчика.Name— Имя счётчика.
Instance-методы:
Increment— Инкрементирование счётчика со стандартным или указанным шагом.Decrement— Декрементирование счётчика со стандартным или указанным шагом.SetValidator— Установка валидатора допустимых значений (можно лямбдой). При невалидном результате (в том числе при установке валидатора) возникнет исключениеCounterNotValidValueException, которое имеет следующие свойства:Counter— Счётчик, с которым связано исключение.OperationType— Перечисление, хранящее операцию, которая осуществлялась со счётчиком:SetValidator— Устанавливался валидатор.Increment— Значение счётчика увеличивалось.Decrement— Значение счётчика уменьшалось.
Step— Шаг, на который изменялось значение счётчика.
Clone— Клонирование счётчика.CompareTo— Сравнение счётчиков.Equals— Проверка счётчика на равенство (по значениямNameиValue).GetHashCode— Переопределён для получения хеш-кода (по значениямNameиValue).ToString— Преобразование счётчика в строковое значение.
Статические методы:
CreateCounter— Фабрика счётчиков с указанными значениями.CreateClosuredCounter— Создание счётчика на основе замыкания.
Операторы:
+=— Увеличивает значение счётчика на указанный шаг.-=— Уменьшает значение счётчика на указанный шаг.++— Увеличивает значение счётчика на стандартный шаг.--— Уменьшает значение счётчика на стандартный шаг.+ double— Увеличивает значение счётчика на указанный шаг.- double— Уменьшает значение счётчика на указанный шаг.==— Проверка счётчика на равенство (по значениямNameиValue).!=— Проверка счётчика на неравенство (по значениямNameиValue).>— Сравнение двух счётчиков с помощьюCompareTo.>=— Сравнение двух счётчиков с помощьюCompareTo.<— Сравнение двух счётчиков с помощьюCompareTo.<=— Сравнение двух счётчиков с помощьюCompareTo.
Подписка на события:
Handler— Событие, принимающее делегат, который будет вызываться при операциях, изменяющих значение счётчика.CounterEventHandler— ДелегатAction<CounterOperationType, long, Counter>, принимаемый событиемHandler:CounterOperationType— Тип операции, производимый над счётчиком, всё те же:SetValidator— Установка валидатора (но при установке валидатора событие не вызывается).Increment— Увеличение значения счётчика.Decrement— Уменьшение значения счётчика.
long— Шаг, на который изменялся счётчик.Counter— Сам счётчик, связанный с событием.
Примеры кода
Со счётчиком на основе замыкания:
var cnt = Counter.CreateClosuredCounter(10);
for (int i = 0; i < 10; i++)
Console.Write(cnt() + " ");
// 10 11 12 13 14 15 16 17 18 19
С обычным счётчиком:
Counter counter = new(value: 0, name: "Подпесчеки");
counter += 10;
counter++;
Console.WriteLine(counter); // "Подпесчеки: 11"
С подпиской на событие:
// Main:
Counter counter = new(0, "Подпесчеки");
counter.Handler += CounterEventHandler;
counter
.Increment()
.Increment(100)
.Decrement()
.Decrement(12);
// Метод-обработчик (название можно и другое):
static void CounterEventHandler(CounterOperationType type, long step, Counter counter) =>
Console.WriteLine($"Операция: {type, -10} | Шаг: {step, - 10} | Имя счётчика: {counter.Name}");
// Вывод в консоль:
Операция: Increment | Шаг: 1 | Имя счётчика: Подпесчеки
Операция: Increment | Шаг: 100 | Имя счётчика: Подпесчеки
Операция: Decrement | Шаг: 1 | Имя счётчика: Подпесчеки
Операция: Decrement | Шаг: 12 | Имя счётчика: Подпесчеки
Verifier
Назначение
Статический класс для проверки объектов, имеющих атрибуты валидации.
Структура
Статические методы:
Check— Проверяет валидируемый объект и возвращаетResult<T, IReadOnlyList<ValidationResult>>, гдеT— тип валидируемого объекта.ThrowIfNotValid— Кидает исключениеVerifierException, если модель не валидна, хранящее сообщения об ошибках и саму модель.
Примеры кода
Класс с атрибутами валидации:
public class User
{
public User(string name, int age) => (Name, Age) = (name, age);
[Required]
[StringLength(20, MinimumLength = 3)]
public string Name { get; private init; }
[Required]
[Range(18, 45)]
public int Age { get; private init; }
}
Проверка на валидность:
// Валидное имя - ↓ ↓ - Невалидный возраст
User user = new("Васили", 17);
var verifyResult = Verifier.Check(user);
if (!verifyResult.IsValid)
{
foreach (var error in verifyResult.Error)
Console.WriteLine(error.ErrorMessage); // The field Age must be between 18 and 45.
return;
}
else
DoSomething(user);
Custom Attributes
Назначение
Дополнительные атрибуты для валидации моделей, и шаблон их создания.
Структура
Дополнительные атрибуты:
ContainsAttribute— Проверяет наличие в строке указанной подстроки (поддерживает переопределение сообщения об ошибке с возможностями интернирования подстроки).InternalizationSupportedAttribute— Проверяет возможность интернировать в строку количество переменных, указанных в конструкторе атрибута (поддерживает переопределение сообщения об ошибке с возможностями интернирования количества переменных).
Примеры кода
Модель с указанными атрибутами:
public class Something
{
public Something(string maskForIntern, string textWithContainsValue) =>
(MaskForIntern, TextWithContainsValue) = (maskForIntern, textWithContainsValue);
[InternalizationSupported(1)] // Поддержка интернирования одной переменной в строку
public string MaskForIntern { get; private init; }
[Contains("TEST")] // Содержание подстроки "TEST"
public string TextWithContainsValue { get; private init; }
}
О методе валидации подобных моделей подробнее написано в этом разделе.
Шаблон для создания атрибутов и исключение AttributeParametersException
Абстрактный класс для создания атрибутов валидации ValidationAttributeTemplate<TAttributeTarget> требует указания в Generic-параметре типа поля, свойства или класса, валидность которого проверяется, и переопределения следующих методов:
private protected override (bool IsValid, string? Error) IsValidAttributeParameters()— Проверяет корректность параметров, указанных в самом атрибуте.private protected override (bool IsValid, string? Error) IsValidTargetValue(TAttributeTarget)— Проверяет корректность поля, свойства или класса.
Данный класс также поддерживает переопределение стандартных сообщений об ошибках, причём и с интернированием указанных параметров. Для этого необходимо в конструктор передать сообщение об ошибке и сами параметры для интернирования. Если строка поддерживает форматирование указанного количества параметров, они будут включены в итоговое строковое значение. Если параметры не указаны, будет просто возвращена заданная строка с ошибкой. Ну а если не указана сама строка, то будет возвращена ошибка либо из IsValidTargetValue, либо стандартное значение Validation error в случае возврата null.
Если IsValidAttributeParameters вернёт false, будет выброшено исключение AttributeParametersException, которое хранит параметры, указанные в конструкторе базового класса (да, их указание требуется не только для интернирования в сообщение об ошибке).
Пример:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class ContainsAttribute : ValidationAttributeTemplate<string>
{
private string _stringForCheckContains;
// С помощью базового конструктора переопределяется сообщение об ошибке, интернируются указанные парметры и формируется исключение
// ↓ ↓ ↓
public ContainsAttribute(string stringForCheckContains, string? errorMessage = null) : base(errorMessage, stringForCheckContains) =>
_stringForCheckContains = stringForCheckContains;
private protected override (bool IsValid, string? Error) IsValidAttributeParameters()
{
if (string.IsNullOrEmpty(_stringForCheckContains))
return (false, "The string whose contents are being checked cannot be empty");
else
return (true, null);
}
private protected override (bool IsValid, string? Error) IsValidTargetValue(string validable)
{
if (validable.Contains(_stringForCheckContains))
return (true, null);
else
return (false, $"The string should contain the \"{_stringForCheckContains}\"");
}
}
Разделение проверки валидности на два метода необходимо для соблюдения принципа SRP, а также для корректного срабатывания исключений. Если, например, проверку параметров атрибута поставить в конструкторе этого атрибута, то исключения не будут выбрасываться, вместо этого атрибут просто не будет присваиваться, что приведёт к валидности проверяемого типа не зависимо от его значения.
EmailsParser
Назначение
Класс для работы с текстом, содержащим email-адреса.
Структура
Константы:
EmailRegex— Регулярное выражение, для поиска в тексте email-адресов.
Методы:
Replace— Меняет все email-адреса из текста на указанное значение.Parse— Получение коллекции email-адресов, хранящихся в тексте.IsValid— Проверяет email-адрес на валидность.
Примеры кода
Замена:
string textForFormatEmails = EmailsParser.Replace(textWithEmails, "{0}");
Получение коллекции:
List<string> emails = EmailsParser.Parse(textWithEmails);
HtmlHelper
Назначение
Вспомогательный класс, для работы с HTML-текстом.
Структура
Константы:
TagRegex— Регулярное выражение для поиска тегов в тексте
Методы:
TagsClear— Очищает строку от тегов.
Примеры кода
string html = ...;
string textFromHtmlWithoutTags = HtmlHelper.TagsClear(html);
// Пример вывода:
// Инклюзия\r\nБезопасность
ConsoleExtension
Назначение
Статический класс с блоками расширения для консоли.
Структура
Статические методы:
TryReadLine— Работает также как и схожие методы: записывает в out-параметр результат чтения из консоли, возвращая содержит ли этот результат символы.WriteColor— Выводит в консоль текст указанного цвета без\n.WriteColorLine— Выводит в консоль текст указанного цвета с\nна конце.CleanLine— Очищает одну строку от текста.
Примеры кода
TryReadLine:
string result;
while(!Console.TryReadLine(out result))
Console.WriteLine("Необходимо указать значение, повторите ввод!");
WriteColor:
internal static void PrintWelcome(string name)
{
Console.Write("Добро пожаловать в программу, ");
Console.WriteColor(name, ConsoleColor.Red);
Console.Write("!\n");
}
CleanLine:
Console.Write("Текст на 3 секунды...");
Thread.Sleep(3000);
Console.CleanLine();
MessageBox
Назначение
Класс и набор перечислений, предназначенный для работы с окнами уведомлений в проектах, не подразумевающих работу на базе фреймворков графических интерфейсов.
Структура
Статический класс MessageBox:
Show— Метод вывода окна уведомлений. Принимает текст уведомления, заголовок окна и его тип (либо битовое полеMessageBoxType, либо объектMessageBoxOptions).
Структура битового поля и объекта с опциями схожа:
WindowType— Типы окон:Ok— Только кнопка "Ок". (default)OkCancel— Кнопки "Ок" и "Закрыть".AbortRetryIgnore— Кнопки "Прервать", "Повторить" и "Пропустить".YesNoCancel— Кнопки "Да", "Нет" и "Закрыть".YesNo— Кнопки "Да" и "Нет".RetryCancel— Кнопки "Повторить" и "Закрыть".CancelTryContinue— Кнопки "Закрыть", "Повторить" и "Продолжить".
DefaultButton— Выбранная кнопка по умолчанию:Button1— Первая кнопка выбрана по умолчанию. (default)Button2— Соответственно.Button3— Соответственно.Button4— Соответственно.
IconType— Иконка окна уведомления:None— Отсутствие иконки. (default)Error— Красный знак ошибки.Question— Знак вопроса.Warning— Жёлтый знак предупреждения.Information— Синий информационный знак.
Статический класс с результатами окна уведомления MessageBoxResult:
Ok.Cancel.Abort.Retry.Ignore.Yes.No.Close.Help.Try.Continue.
Примеры кода
С битовым полем:
int result = MessageBox.Show(
"Продолжить работу программы?",
"Окно уведомлений",
MessageBoxType.Window_YesNoCancel | MessageBoxType.DefaultButton_2 | MessageBoxType.Icon_Question);
if (result == MessageBoxResult.Yes)
Console.WriteLine("Я каменщик, работаем дальше...");
else if (result == MessageBoxResult.No)
Console.WriteLine("User'а ответ!");
else
return;
С объектом опций:
MessageBoxOptions options = new(WindowType.OkCancel, IconType.Information, DefaultButton.Button2);
MessageBox.Show("Это окно можно закрыть", "Информационное окно", options);
Reflection
Назначение
Статический класс, предназначенный для исследования пользовательских типов.
Структура
Атрибуты:
ReflectionAttribute(BindingFlags(optional))— Атрибут для отметки класса о необходимости осуществления его рефлексивного анализа методомReflection.Print();
Статические методы:
Print()— Выводит информацию о всех пользовательских типах, имеющих атрибутReflectionAttribute(только этот метод связан с использованием атрибута);Print(Type, BindingFlags(optional))— Выводит рефлексивную информацию о переданном в параметр типе согласно указанным флагам.Print(Assembly, BindingFlags(optional))— Выводит рефлексивную информацию о переданной в параметр сборке.Print(String, BindingFlags(optional))— Выводит рефлексивную информацию о сборке, путь которой передан в параметр метода.Print(String, String, BindingFlags(optional))— Выводит рефлексивную информацию о сборке, чей путь указан, и содержащимся в ней типе, название которого указано вторым параметром.
Примеры кода
Использование через атрибут:
// Main:
Reflection.Print();
// Тестовый класс для анализа
[Reflection]
public class ClassTest
{
private static int count = 0;
private string? name;
private Func<int>? getNumber;
public string? Name => name;
public ClassTest(string name) { }
public ClassTest() { }
public event Func<int> GetNumber
{
add
{
if (value == null)
return;
getNumber += value;
}
remove
{
if (value == null || getNumber == null)
return;
if (!getNumber.GetInvocationList().Contains(value))
return;
getNumber -= value;
}
}
internal void Print(string mess, string mess2) { }
}
// Вывод:
// Состав сборки "SandBox.dll":
//
// Класс "ClassTest":
// |
// | Поля:
// | |
// | | Имя: name | Тип: System.String | Атрибуты: Private
// | | Имя: getNumber | Тип: System.Func`1[System.Int32] | Атрибуты: Private
// | | Имя: count | Тип: System.Int32 | Атрибуты: Private, Static
// | |
// | Общее количество: 3
// |
// | Методы:
// | |
// | | Имя: get_Name
// | | Атрибуты: Public, HideBySig, SpecialName
// | | Возвращаемый тип: System.String
// | |
// | | Имя: add_GetNumber
// | | Атрибуты: Public, HideBySig, SpecialName
// | | Возвращаемый тип: Void
// | | Параметры: (System.Func`1[System.Int32]) value
// | |
// | | Имя: remove_GetNumber
// | | Атрибуты: Public, HideBySig, SpecialName
// | | Возвращаемый тип: Void
// | | Параметры: (System.Func`1[System.Int32]) value
// | |
// | | Имя: Print
// | | Атрибуты: Assembly, HideBySig
// | | Возвращаемый тип: Void
// | | Параметры: (System.String) mess, (System.String) mess2
// | |
// | Общее количество: 4
// |
// | Конструкторы:
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.String) name
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | |
// | Общее количество: 2
// |
// Конец класса
//
// Конец сборки
Использование по ссылке на тип (поисследуем класс String):
// Main:
Reflection.Print(typeof(System.String));
// Вывод:
// Состав сборки "System.Private.CoreLib.dll":
//
// Класс "String":
// |
// | Поля:
// | |
// | | Имя: _stringLength | Тип: System.Int32 | Атрибуты: Private, InitOnly, NotSerialized
// | | Имя: _firstChar | Тип: System.Char | Атрибуты: Private, NotSerialized
// | | Имя: Empty | Тип: System.String | Атрибуты: Public, Static, InitOnly
// | |
// | Общее количество: 3
// |
// | Методы:
// | |
// | | Имя: FastAllocateString
// | | Атрибуты: Assembly, Static, HideBySig
// | | Возвращаемый тип: System.String
// | | Параметры: (System.Int32) length
// | |
// Тут очень много методов, можете при желании поисследовать сами
// | |
// | | Имя: LastIndexOf
// | | Атрибуты: Public, HideBySig
// | | Возвращаемый тип: Int32
// | | Параметры: (System.String) value, (System.Int32) startIndex, (System.Int32) count, (System.StringComparison) comparisonType
// | |
// | Общее количество: 267
// |
// | Конструкторы:
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.Char[]) value
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.Char[]) value, (System.Int32) startIndex, (System.Int32) length
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.Char*) value
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.Char*) value, (System.Int32) startIndex, (System.Int32) length
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.SByte*) value
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.SByte*) value, (System.Int32) startIndex, (System.Int32) length
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.SByte*) value, (System.Int32) startIndex, (System.Int32) length, (System.Text.Encoding) enc
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.Char) c, (System.Int32) count
// | |
// | | Имя: .ctor
// | | Атрибуты: Public, HideBySig, SpecialName, RTSpecialName
// | | Параметры: (System.ReadOnlySpan`1[System.Char]) value
// | |
// | Общее количество: 9
// |
// Конец класса
//
// Конец сборки
Использование по ссылке на сборку:
Reflection.Print(Assembly.GetAssembly(typeof(Regex)));
// Выведет все классы, входящие в состав "System.Text.RegularExpressions.dll"
Использование через указание пути сборки:
↓ - экранирование знака "\"
string pathAssembly = "D:\\csharp\\projects\\ExtraLib\\bin\\Debug\\net9.0\\Text.dll";
Reflection.Print(pathAssembly);
Использование через указание пути сборки и названия класса:
↓ - экранирование знака "\"
string pathAssembly = "D:\\csharp\\projects\\ExtraLib\\bin\\Debug\\net9.0\\Std.dll";
Reflection.Print(pathAssembly, "Comparator");
// Или по полному названию
Reflection.Print(pathAssembly, "Std.Comparator");
// Если полученную сборку не удастся открыть, будет выведено сообщение из Exception
// Could not load file or assembly 'D:\csharp\projects\ExtraLib\bin\Debug\net9.0\Std.dll'. Системе не удается найти указанный путь.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on san40_u5an40.ExtraLib:
| Package | Downloads |
|---|---|
|
san40_u5an40.ConsoleDisplayFramework
Framework for fast creation of console display |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 5.4.0 | 147 | 7/8/2026 |
| 5.3.0 | 116 | 7/7/2026 |
| 5.2.0 | 123 | 6/7/2026 |
| 5.1.0 | 125 | 5/15/2026 |
| 5.0.2 | 127 | 4/27/2026 |
| 5.0.1 | 140 | 2/12/2026 |
| 5.0.0 | 131 | 2/12/2026 |
| 4.4.0 | 132 | 2/9/2026 |
| 4.3.0 | 132 | 2/7/2026 |
| 4.2.0 | 174 | 2/7/2026 |
| 4.1.0 | 136 | 2/6/2026 |
| 4.0.1 | 129 | 2/5/2026 |
| 4.0.0 | 140 | 2/5/2026 |
| 3.0.0 | 148 | 1/29/2026 |
| 2.0.0 | 136 | 1/18/2026 |
| 1.3.1 | 138 | 1/15/2026 |
| 1.3.0 | 132 | 1/14/2026 |
| 1.2.0 | 517 | 12/8/2025 |
| 1.1.0 | 241 | 11/23/2025 |
| 1.0.1 | 441 | 11/19/2025 |
Улучшена потокобезопасность Counter