que - clase enum c#
¿Cuál es la tilde(~) en la definición de enum? (10)
Siempre me sorprende que incluso después de usar C # durante todo este tiempo, aún logré encontrar cosas que no sabía ...
Intenté buscar en Internet esto, pero usar el "~" en una búsqueda no me funciona tan bien y tampoco encontré nada en MSDN (por no decir que no está allí)
Recientemente vi este fragmento de código, ¿qué significa la tilde (~)?
/// <summary>
/// Enumerates the ways a customer may purchase goods.
/// </summary>
[Flags]
public enum PurchaseMethod
{
All = ~0,
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4
}
Me sorprendió un poco verlo, así que traté de compilarlo, y funcionó ... pero todavía no sé lo que significa / hace. ¿¿Alguna ayuda??
Es mejor que el
All = Cash | Check | CreditCard
solución, porque si agrega otro método más tarde, diga:
PayPal = 8 ,
ya habrás terminado con la tilde-Todo, pero tendrás que cambiar la línea general por la otra. Por lo tanto, es menos propenso a errores más adelante.
Saludos
Es un operador de complemento. Aquí hay un artículo que a menudo me refiero para operadores de bit a bit
http://www.blackwasp.co.uk/CSharpLogicalBitwiseOps.aspx
También msdn lo usa en su artículo de enums que demuestra que usa mejor
He hecho algunos experimentos con el ~ y me parece que podría haber peligros. Considere este fragmento de LINQPad que muestra que el valor de Todas las enumeraciones no se comporta como se espera cuando todos los valores se fusionan.
void Main()
{
StatusFilterEnum x = StatusFilterEnum.Standard | StatusFilterEnum.Saved;
bool isAll = (x & StatusFilterEnum.All) == StatusFilterEnum.All;
//isAll is false but the naive user would expect true
isAll.Dump();
}
[Flags]
public enum StatusFilterEnum {
Standard =0,
Saved =1,
All = ~0
}
La alternativa que personalmente uso, que hace lo mismo que la respuesta de @Sean Bright pero me parece mejor, es esta:
[Flags]
public enum PurchaseMethod
{
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4,
PayPal = 8,
BitCoin = 16,
All = Cash + Check + CreditCard + PayPal + BitCoin
}
Observe cómo la naturaleza binaria de esos números, que son todos los poderes de dos, hace verdadera la siguiente aserción: (a + b + c) == (a | b | c)
. Y en mi humilde opinión, +
ve mejor.
Para otros que encontraron esta pregunta esclarecedora, tengo un rápido ~
ejemplo para compartir. El siguiente fragmento de la implementación de un método de pintura, como se detalla en esta documentación de Mono , usa ~
con gran efecto:
PaintCells (clipBounds,
DataGridViewPaintParts.All & ~DataGridViewPaintParts.SelectionBackground);
Sin el operador ~
, el código probablemente se vería así:
PaintCells (clipBounds, DataGridViewPaintParts.Background
| DataGridViewPaintParts.Border
| DataGridViewPaintParts.ContentBackground
| DataGridViewPaintParts.ContentForeground
| DataGridViewPaintParts.ErrorIcon
| DataGridViewPaintParts.Focus);
... porque la enumeración se ve así:
public enum DataGridViewPaintParts
{
None = 0,
Background = 1,
Border = 2,
ContentBackground = 4,
ContentForeground = 8,
ErrorIcon = 16,
Focus = 32,
SelectionBackground = 64,
All = 127 // which is equal to Background | Border | ... | Focus
}
¿Nota la similitud de esta enum con la respuesta de Sean Bright?
Creo que lo más importante para mí es que ~
es el mismo operador en una enumeración que en una línea normal de código.
Solo quiero agregar, si usa [Flags] enum, entonces puede ser más conveniente usar un operador de desplazamiento a la izquierda bit a bit, como este:
[Flags]
enum SampleEnum
{
None = 0, // 0
First = 1 << 0, // 1b = 1d
Second = 1 << 1, // 10b = 2d
Third = 1 << 2, // 100b = 4d
Fourth = 1 << 3, // 1000b = 8d
All = ~0 // 11111111b
}
Solo una nota al margen, cuando uses
All = Cash | Check | CreditCard
usted tiene el beneficio adicional de que Cash | Check | CreditCard
Cash | Check | CreditCard
Cash | Check | CreditCard
evaluaría a All
y no a otro valor (-1) que no es igual a todos mientras contiene todos los valores. Por ejemplo, si usa tres casillas de verificación en la interfaz de usuario
[] Cash
[] Check
[] CreditCard
y sume sus valores, y el usuario los selecciona a todos, verá All
en la enumeración resultante.
Yo pensaría que:
[Flags]
public enum PurchaseMethod
{
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4,
All = Cash | Check | CreditCard
}
Sería un poco más claro.
~ es el operador complementario de unario: voltea los bits de su operando.
~0 = 0xFFFFFFFF = -1
en aritmética de complemento a dos, ~x == -x-1
el ~ operador se puede encontrar en prácticamente cualquier lenguaje que tome prestada la sintaxis de C, incluido Objective-C / C ++ / C # / Java / Javascript.
public enum PurchaseMethod
{
All = ~0, // all bits of All are 1. the ~ operator just inverts bits
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4
}
Debido a dos complementos en C #, ~0 == -1
, el número donde todos los bits son 1 en la representación binaria.