Удалена поддержка Boolean
enum, а также прекращена поддержка net45 и увеличена до net461 из-за обновления зависимостей. Также прекращена поддержка netstandard 1.x tfms по аналогичной причине. Добавлена цель сборки net7, которая использует встроенные универсальные интерфейсы чисел. Также добавлен базовый класс EnumValidatorAttribute
, так как теперь поддерживаются универсальные атрибуты.
Удалены классы NonGenericEnums
, NonGenericFlagEnums
, UnsafeEnums
, и UnsafeFlagEnums
, которые были отмечены как устаревшие в версии 3.0, а также удалены все остальные устаревшие методы с целью уменьшения размера библиотеки. При переходе с версий 2.x и ниже рекомендуется сначала обновиться до версии 3.x и следовать предупреждениям по миграции любого кода, который использует устаревшие методы и классы. Кроме того, добавлена зависимость от пакета System.Runtime.CompilerServices.Unsafe
для цели сборки .NET 4.5 с целью удаления зависимости от сборки Fody
.# Enums.NET
Enums.NET — это высокопроизводительная типобезопасная библиотека для работы с перечислениями (.NET enum) в среде .NET, предоставляющая множество операций в виде удобных расширений. Она совместима с .NET Framework Yöntem, который не является типобезопасным, неэффективен и неясен относительно того, проверяет ли он наличие всех или любых указанных флагов. Это всё равно.
2. Большинство его методов используют рефлексию при каждом вызове без какого-либо кэширования, что приводит к плохой производительности.
3. Шаблон использования атрибутов для связи дополнительных данных с членами перечисления не поддерживается, вместо этого требуются пользователи самостоятельно получать эти атрибуты через рефлексию. Этот шаблон часто используется для членов перечислений с атрибутами DescriptionAttribute
, EnumMemberAttribute
и DisplayAttribute
. Enums.NET решает все эти проблемы и ещё больше.
using System;
using System.Linq;
using EnumsNET;
using Xunit;
using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
class EnumsNETDemo
{
// Определения перечислений в конце
Исправление:
# Enums.NET
Enums.NET — это высокопроизводительная типобезопасная библиотека для работы с перечислениями (.NET enum) в среде .NET, предоставляющая множество операций в виде удобных расширений. Она совместима с .NET Framework 4.6.1+ и .NET Standard 2.0+.
## Что не так со `System.Enum`
1. Поддержка перечислений с флагами ограничена методом `HasFlag`, который не является типобезопасным, неэффективен и неясен относительно того, проверяет ли он наличие всех или любых указанных флагов. Это всё равно.
2. Большинство его методов используют рефлексию при каждом вызове без какого-либо кэширования, что приводит к плохой производительности.
3. Шаблон использования атрибутов для связи дополнительных данных с членами перечисления не поддерживается, вместо этого требуются пользователи самостоятельно получать эти атрибуты через рефлексию. Этот шаблон часто используется для членов перечислений с атрибутами `DescriptionAttribute`, `EnumMemberAttribute` и `DisplayAttribute`. Enums.NET решает все эти проблемы и ещё больше.
## Демонстрация Enums.NET
```c#
using System;
using System.Linq;
using EnumsNET;
using Xunit;
using DescriptionAttribute = System.ComponentModel.DescriptionAttribute;
class EnumsNETDemo
{
// Определения перечислений в конце
public void ПереборПеречислений()
{
int count = 0;
// Получение всех членов перечисления в порядке возрастания значений
foreach (var member in Enums.GetMembers<NumericOperator>())
{
NumericOperator значение = member.Value;
string имя = member.Name;
AttributeCollection атрибуты = member.Attributes;
++count;
}
Assert.Equal(8, count);
}```csharp
count = 0;
// Получение уникальных значений в порядке возрастания значений
foreach (var value in Enums.GetValues<NumericOperator>(EnumMemberSelection.Distinct))
{
string name = value.GetName();
AttributeCollection attributes = value.GetAttributes();
++count;
}
Assert.Equal(6, count);
}
[Fact]
public void OperationsWithFlagEnumerations()
{
// Все флаги присутствуют
Assert.True((DaysOfWeek.Monday | DaysOfWeek.Wednesday | DaysOfWeek.Friday).HasAllFlags(DaysOfWeek.Monday | DaysOfWeek.Wednesday));
Assert.False(DaysOfWeek.Monday.HasAllFlags(DaysOfWeek.Monday | DaysOfWeek.Wednesday));
// Любые флаги присутствуют
Assert.True(DaysOfWeek.Monday.HasAnyFlags(DaysOfWeek.Monday | DaysOfWeek.Wednesday));
Assert.False((DaysOfWeek.Monday | DaysOfWeek.Wednesday).HasAnyFlags(DaysOfWeek.Friday));
// Объединение флагов ~ побитовое ИЛИ
Assert.Equal(DaysOfWeek.Monday | DaysOfWeek.Wednesday, DaysOfWeek.Monday.CombineFlags(DaysOfWeek.Wednesday));
Assert.Equal(DaysOfWeek.Monday | DaysOfWeek.Wednesday | DaysOfWeek.Friday, FlagEnums.CombineFlags(DaysOfWeek.Monday, DaysOfWeek.Wednesday, DaysOfWeek.Friday));
// Общие флаги ~ побитовое И
Assert.Equal(DaysOfWeek.Monday, DaysOfWeek.Monday.CommonFlags(DaysOfWeek.Monday | DaysOfWeek.Wednesday));
Assert.Equal(DaysOfWeek.None, DaysOfWeek.Monday.CommonFlags(DaysOfWeek.Wednesday));
// Удаление флагов
Assert.Equal(DaysOfWeek.Wednesday, (DaysOfWeek.Monday | DaysOfWeek.Wednesday).RemoveFlags(DaysOfWeek.Monday));
Assert.Equal(DaysOfWeek.None, (DaysOfWeek.Monday | DaysOfWeek.Wednesday).RemoveFlags(DaysOfWeek.Monday | DaysOfWeek.Wednesday));
}
// Получение флагов, разделение отдельных флагов в порядке возрастания значимости битов
var flags = DaysOfWeek.Weekend.GetFlags();
Assert.Equal(2, flags.Count);
Assert.Equal(DaysOfWeek.Sunday, flags[0]);
Assert.Equal(DaysOfWeek.Saturday, flags[1]);
```[Факт]
public void AsString()
{
// AsString, эквивалент метода ToString
Assert.Equal("Равно", NumericOperator.Equals.AsString());
Assert.Equal("-1", ((NumericOperator)(-1)).AsString());
// Получение имени
Assert.Equal("Равно", NumericOperator.Equals.GetName());
Assert.Null(((NumericOperator)(-1)).GetName());
// Получение описания
Assert.Equal("Является", NumericOperator.Equals.AsString(EnumFormat.Description));
Assert.Null(NumericOperator.LessThan.AsString(EnumFormat.Description));
// Получение описания, если применимо, в противном случае имя
Assert.Equal("Меньше", NumericOperator.LessThan.AsString(EnumFormat.Description, EnumFormat.Name));
}
[Факт]
public void Validate()
{
// Обычные перечисления, проверка наличия определения
Assert.True(NumericOperator.LessThan.IsValid());
Assert.False(((NumericOperator)20).IsValid());
// Перечисления с флагами, проверка корректности комбинаций флагов или наличия определения
Assert.True((DaysOfWeek.Sunday | DaysOfWeek.Wednesday).IsValid());
Assert.False((DaysOfWeek.Sunday | DaysOfWeek.Wednesday | ((DaysOfWeek)(-1))).IsValid());
// Пользовательская валидация через IEnumValidatorAttribute<TEnum>
Assert.True(DayType.Weekday.IsValid());
Assert.True((DayType.Weekday | DayType.Holiday).IsValid());
Assert.False((DayType.Weekday | DayType.Weekend).IsValid());
}
[Факт]
public void CustomEnumFormat()
{
EnumFormat symbolFormat = Enums.RegisterCustomEnumFormat(member => member.Attributes.Get<SymbolAttribute>()?.Symbol);
Assert.Equal(">", NumericOperator.GreaterThan.AsString(symbolFormat));
Assert.Equal(NumericOperator.LessThan, Enums.Parse<NumericOperator>("<", ignoreCase: false, symbolFormat));
}```csharp
[Fact]
public void Attributes()
{
Assert.Equal("!=", NumericOperator.NotEquals.GetAttributes().Get<SymbolAttribute>().Symbol);
Assert.True(Enums.GetMember<NumericOperator>("GreaterThanOrEquals").Attributes.Has<PrimaryEnumMemberAttribute>());
Assert.False(NumericOperator.LessThan.GetAttributes().Has<DescriptionAttribute>());
}
[Факт]
public void Парсинг()
{
Assert.Equal(NumericOperator.GreaterThan, Enums.Parse<NumericOperator>("Больше"));
Assert.Equal(NumericOperator.NotEquals, Enums.Parse<NumericOperator>("1"));
Assert.Equal(NumericOperator.Equals, Enums.Parse<NumericOperator>("Идентично", ignoreCase: false, EnumFormat.Description));
}
``` Assert.Equal(ДниНедели.Понедельник | ДниНедели.Среда, Enums.Parse<ДниНедели>("Понедельник, Среда"));
Assert.Equal(ДниНедели.Вторник | ДниНедели.Четверг, FlagEnums.ParseFlags<ДниНедели>("Вторник | Четверг", ignoreCase: false, delimiter: "|"));
}
enum ЧисловойОператор
{
[Символ("="), Описание("Идентично")]
Равно,
[Символ("!="), Описание("Не идентично")]
НеРавно,
[Символ("<")]
Меньше,
[Символ(">="), ПервичныйЭлементПеречисления] // ПервичныйЭлементПеречисления указывает элемент перечисления как основной дубликат для расширяемых методов
БольшеИлиРавно,
НеМеньше = БольшеИлиРавно,
[Символ(">")]
Больше,
[Символ("<="), ПервичныйЭлементПеречисления]
МеньшеИлиРавно,
НеБольше = МеньшеИлиРавно
}
[АтрибутUsage(AttributeTargets.Field)]
class SymbolAttribute : Attribute
{
public string Symbol { get; }
public SymbolAttribute(string symbol)
{
Symbol = symbol;
}
}
[Flags]
enum ДниНедели
{
Ничего = 0,
Воскресенье = 1,
Понедельник = 2,
Вторник = 4,
Среда = 8,
Четверг = 16,
Пятница = 32,
РабочиеДни = Понедельник | Вторник | Среда | Четверг | Пятница,
Суббота = 64,
Выходной = Воскресенье | Суббота,
Все = Воскресенье | Понедельник | Вторник | Среда | Четверг | Пятница | Суббота
}
[Flags, DayTypeValidator]
enum DayType
{
РабочийДень = 1,
Выходной = 2,
Праздничный = 4
} class DayTypeValidatorAttribute : EnumValidatorAttribute<DayType>
{
public override bool IsValid(DayType value) => value.GetFlagCount((DayType)(DayType.RabochiyDen | DayType.Vykhodnoy)) == 1 && FlagEnums.IsValidFlagCombination(value);
}
}
Результаты выполнения BenchmarkDotNet приложения для тестирования производительности.
Для просмотра интерфейса см. FuGet.
Вдохновлен работой Джона Скита Unconstrained Melody.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )