Desafortunadamente, las operaciones de enum de bandera incorporadas de .NET son bastante limitadas. La mayoría de las veces los usuarios se quedan con la lógica de operación bit a bit.
En .NET 4, HasFlag
se agregó el método Enum
que ayuda a simplificar el código del usuario, pero desafortunadamente hay muchos problemas con él.
HasFlag
no es de tipo seguro ya que acepta cualquier tipo de argumento de valor de enumeración, no solo el tipo de enumeración dado.
HasFlag
es ambiguo en cuanto a si verifica si el valor tiene todas o alguna de las banderas proporcionadas por el argumento de valor enum. Es todo por cierto.
HasFlag
es bastante lento ya que requiere un boxeo que causa asignaciones y, por lo tanto, más recolecciones de basura.
Debido en parte al soporte limitado de .NET para las enums de flag, escribí la biblioteca de OSS Enums.NET que aborda cada uno de estos problemas y hace que el manejo de las enums de flag sea mucho más fácil.
A continuación se presentan algunas de las operaciones que proporciona junto con sus implementaciones equivalentes utilizando solo el marco .NET.
Combinar banderas
.RED flags | otherFlags
Enums.NET flags.CombineFlags(otherFlags)
Eliminar banderas
.RED flags & ~otherFlags
Enums.NET flags.RemoveFlags(otherFlags)
Banderas Comunes
.RED flags & otherFlags
Enums.NET flags.CommonFlags(otherFlags)
Alternar banderas
.RED flags ^ otherFlags
Enums.NET flags.ToggleFlags(otherFlags)
Tiene todas las banderas
.NET (flags & otherFlags) == otherFlags
oflags.HasFlag(otherFlags)
Enums.NET flags.HasAllFlags(otherFlags)
Tiene banderas
.RED (flags & otherFlags) != 0
Enums.NET flags.HasAnyFlags(otherFlags)
Obtener banderas
.RED
Enumerable.Range(0, 64)
.Where(bit => ((flags.GetTypeCode() == TypeCode.UInt64 ? (long)(ulong)flags : Convert.ToInt64(flags)) & (1L << bit)) != 0)
.Select(bit => Enum.ToObject(flags.GetType(), 1L << bit))`
Enums.NET flags.GetFlags()
Estoy tratando de incorporar estas mejoras en .NET Core y quizás eventualmente en el .NET Framework completo. Puedes ver mi propuesta aquí .