¿Por qué los permisos de enumeración a menudo tienen 0, 1, 2, 4 valores?
¿Por qué la gente siempre usa valores de enumeración como 0, 1, 2, 4, 8
y no 0, 1, 2, 3, 4
?
Tiene algo que ver con operaciones de bits, etc.?
Realmente apreciaría un pequeño fragmento de muestra sobre cómo se usa correctamente :)
[Flags]
public enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
7 answers
Porque son poderes de dos y puedo hacer esto: {[10]]}
var permissions = Permissions.Read | Permissions.Write;
Y quizás más tarde...
if( (permissions & Permissions.Write) == Permissions.Write )
{
// we have write access
}
Es un campo de bits, donde cada bit establecido corresponde a algún permiso (o a lo que corresponda lógicamente el valor enumerado). Si estos se definieran como 1, 2, 3, ...
no sería capaz de usar operadores bitwise de esta manera y obtener resultados significativos. Para profundizar...
Permissions.Read == 1 == 00000001
Permissions.Write == 2 == 00000010
Permissions.Delete == 4 == 00000100
¿Notas un patrón aquí? Ahora si tomamos mi ejemplo original, i. e.,
var permissions = Permissions.Read | Permissions.Write;
Entonces...
permissions == 00000011
¿Ves? Tanto los bits Read
como Write
están establecidos, y puedo comprobarlo de forma independiente (También observe que el bit Delete
es no establecido y, por lo tanto, este valor no transmite permiso para eliminar).
Permite almacenar múltiples banderas en un solo campo de bits.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-21 19:14:47
Si todavía no está claro en las otras respuestas, piénsalo así:
[Flags]
public enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
Es solo una forma más corta de escribir:
public enum Permissions
{
DeleteNoWriteNoReadNo = 0, // None
DeleteNoWriteNoReadYes = 1, // Read
DeleteNoWriteYesReadNo = 2, // Write
DeleteNoWriteYesReadYes = 3, // Read + Write
DeleteYesWriteNoReadNo = 4, // Delete
DeleteYesWriteNoReadYes = 5, // Read + Delete
DeleteYesWriteYesReadNo = 6, // Write + Delete
DeleteYesWriteYesReadYes = 7, // Read + Write + Delete
}
Hay ocho posibilidades pero puedes representarlas como combinaciones de solo cuatro miembros. Si hubiera dieciséis posibilidades, entonces podrías representarlas como combinaciones de solo cinco miembros. ¡Si hubiera cuatro mil millones de posibilidades, entonces podrías representarlas como combinaciones de solo 33 miembros! Obviamente, es mucho mejor tener solo 33 miembros, cada uno (excepto cero) una potencia de dos, que tratar de nombrar cuatro mil millones de artículos en una enumeración.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-19 11:55:13
Porque estos valores representan ubicaciones de bits únicas en binario:
1 == binary 00000001
2 == binary 00000010
4 == binary 00000100
Etc., so
1 | 2 == binary 00000011
EDITAR:
3 == binary 00000011
3 en binario está representado por un valor de 1 tanto en el lugar de las unidades como en el lugar de los dos. En realidad es el mismo que el valor 1 | 2
. Así que cuando usted está tratando de utilizar los lugares binarios como banderas para representar algún estado, 3 no suele ser significativo (a menos que haya un valor lógico que en realidad es la combinación de los dos)
Para más aclaración, es posible que desee extender su enumeración de ejemplo de la siguiente manera:
[Flags]
public Enum Permissions
{
None = 0, // Binary 0000000
Read = 1, // Binary 0000001
Write = 2, // Binary 0000010
Delete = 4, // Binary 0000100
All = 7, // Binary 0000111
}
Por lo tanto en tengo Permissions.All
, también tengo implícitamente Permissions.Read
, Permissions.Write
, y Permissions.Delete
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-21 19:18:39
[Flags]
public Enum Permissions
{
None = 0; //0000000
Read = 1; //0000001
Write = 1<<1; //0000010
Delete = 1<<2; //0000100
Blah1 = 1<<3; //0001000
Blah2 = 1<<4; //0010000
}
Creo que escribir así es más fácil de entender y leer, y no es necesario calcularlo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-23 19:42:15
Se utilizan para representar indicadores de bits que permiten combinaciones de valores de enumeración. Creo que es más claro si escribes los valores en notación hexadecimal
[Flags]
public Enum Permissions
{
None = 0x00,
Read = 0x01,
Write = 0x02,
Delete= 0x04,
Blah1 = 0x08,
Blah2 = 0x10
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-04 16:44:28
Esto es más bien un comentario, pero como eso no soportaría el formato, solo quería incluir un método que he empleado para configurar enumeraciones de flag:
[Flags]
public enum FlagTest
{
None = 0,
Read = 1,
Write = Read * 2,
Delete = Write * 2,
ReadWrite = Read|Write
}
Encuentro este enfoque especialmente útil durante el desarrollo en el caso en el que te gusta mantener tus banderas en orden alfabético. Si determina que necesita agregar un nuevo valor de bandera, puede insertarlo alfabéticamente y el único valor que debe cambiar es el que ahora precede.
Tenga en cuenta, sin embargo, que una vez que una solución se publica en cualquier sistema de producción (especialmente si la enumeración se expone sin un acoplamiento apretado, como a través de un servicio web), entonces es altamente recomendable contra el cambio de cualquier valor existente dentro de la enumeración.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-23 12:19:16
Muchas buenas respuestas a esta just solo diré.. si no le gusta, o no puede comprender fácilmente lo que la sintaxis <<
está tratando de expresar.. Personalmente prefiero una alternativa (y me atrevo a decir, sencillo enum declaration style) {
typedef NS_OPTIONS(NSUInteger, Align) {
AlignLeft = 00000001,
AlignRight = 00000010,
AlignTop = 00000100,
AlignBottom = 00001000,
AlignTopLeft = 00000101,
AlignTopRight = 00000110,
AlignBottomLeft = 00001001,
AlignBottomRight = 00001010
};
NSLog(@"%ld == %ld", AlignLeft | AlignBottom, AlignBottomLeft);
REGISTRO 513 == 513
Mucho más fácil (por lo menos para mí) de comprender. Alinee los describe describa el resultado que desea, obtenga el resultado que DESEA.. No se necesitan" cálculos".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-25 13:24:59