c# - unity - ¿Qué hace realmente el atributo[Flags]?
remarks c# (6)
¿Qué hace la aplicación [Flags]
realmente?
Sé que modifica el comportamiento de Enum.ToString
, pero ¿hace algo más? (Ej. Comportamiento diferente de compilador o tiempo de ejecución, etc.)
Edit : Sí, soy consciente de que documenta el hecho de que la enumeración está destinada a ser utilizada como indicadores bitwise, y que es más lógico aplicarlo a los indicadores bit. Sin embargo, estaba preguntando más sobre cambios concretos de comportamiento, no sobre prácticas de programación generales.
Aquí hay una lista de diferencias de comportamiento concretas:
- Al establecer una enumeración con [flags] en None se borran todas las banderas.
- El método HasFlags solo funciona cuando este atributo está presente.
- Como dijo Devio, cambia las capacidades de los métodos Parse y Format. Se vinculó a este artículo . Aparentemente también impacta lo que se muestra en Debuggers.
- Pensé que [las banderas] probablemente tenían un impacto en la generación de código en los servicios web, pero parece que este no es el caso.
- Para ser claros, se permiten operaciones bitwise en cualquier enumeración, con o sin [flags]. Pero usarlo es la mejor práctica.
Más detalles: msdn.microsoft.com/en-us/library/ms229062.aspx
Banderas da una opción para usar enumeración para valor múltiple.
Considere una situación en la que desea utilizar las casillas de verificación para situaciones diferentes, pero no desea crear columnas diferentes en la base de datos. Si tiene 20 casillas de verificación, tendrá que crear 20 columnas en la base de datos con bool. Pero con las banderas puede crear una columna y usar ese valor para almacenar en la columna. Ejecute este ejemplo en la consola para entenderlo mejor.
class Program
{
static void Main(string[] args)
{
//Set the features that you require for car. Consider it as checked in the UI.
CarFeatures carFeatures = CarFeatures.AC | CarFeatures.Autopilot| CarFeatures.Sunroof;
//Do the backend logic
if (carFeatures.HasFlag(CarFeatures.Autopilot))
{
//Show Autopilot cars
}
//See the what carfeatures are required
Console.WriteLine(carFeatures);
//See the integer value of the carfeatures
Console.WriteLine((int)carFeatures);
Console.ReadLine();
}
}
[Flags]
public enum CarFeatures
{
AC=1,
HeatedSeats= 2,
Sunroof= 4,
Autopilot= 8,
}
La combinación diferente siempre te da un número único que c # rastrea para encontrar lo que está marcado.
De un artículo de MSDN :
Es interesante observar que cuando se especifican los indicadores, los métodos Parse y Format cuentan con capacidades avanzadas.
Del mismo modo, el método Parse puede analizar con éxito una cadena separada por comas como la que se muestra en el valor numérico adecuado.
En la práctica, uno de los usos que uso es indicar múltiples estados. Esta es una simplificación de algunos códigos que evalúan los resultados de las pruebas. La prueba puede estar bien, o podría tener varias razones para no estar bien. La ventaja que esto da es que tengo un método que evalúa las pruebas de "Ok-ness", y ese método es capaz de indicar todas las posibles condiciones de falla con una devolución. Puede que no sea el mejor diseño, pero funciona en este caso.
[Flags]
public enum ResultStatusEnum
{
Ok = 0x1,
SampleInvalid = 0x2,
DirectionInvalid = 0x4,
TestIsNotValid = 0x8
}
Lo pones así:
ResultStatusEnum res = ResultStatusEnum.SampleInvalid | ResultStatusEnum.DirectionInvalid;
La desventaja es que el control de los valores de la enumeración se vuelve engorroso. Esto no funcionará (necesariamente):
res == ResultStatusEnum.Ok
Tienes que hacer esto para comprobar:
ResultStatusEnum.SampleInvalid == (res & ResultStatusEnum.SampleInvalid)
En este caso, es ilógico tener ResultStatusEnum.Ok & ResultStatusEnum.SampleInvalid
, pero me aseguro de que este no sea el caso en el que utilizo la enumeración.
Si preguntas qué hace bajo el capó, por lo que sé, cambia el método ToString (), nada más.
Bajo .Net 4 tiene el método HasFlags para verificar banderas específicas. Si interpreto msdn a la derecha, tienes que usar el atributo flags para usar este método. Pero no lo he probado.
Vea la publicación de David M. Kean here . Esto parece ser un problema de interoperabilidad de idioma:
Aunque C # permite a los usuarios realizar operaciones de bits en enumeraciones sin el atributo FlagsAttribute, Visual Basic no lo hace. Entonces, si está exponiendo tipos a otros idiomas, entonces marcar las enumeraciones con el atributo FlagsAttribute es una buena idea; también deja claro que los miembros de la enumeración están diseñados para ser utilizados juntos.
Saludos
David