Co to jest tylda ( ~ ) w definicji enum?
Jestem zawsze zaskoczony, że nawet po używaniu C# przez cały ten czas, wciąż udaje mi się znaleźć rzeczy, o których nie wiedziałem...
Próbowałem przeszukiwać internet w poszukiwaniu tego, ale użycie " ~ " w wyszukiwaniu nie działa dla mnie tak dobrze i nie znalazłem nic na MSDN albo (nie mówiąc, że nie ma)
Widziałem ostatnio ten fragment kodu, co oznacza tylda (~)?
/// <summary>
/// Enumerates the ways a customer may purchase goods.
/// </summary>
[Flags]
public enum PurchaseMethod
{
All = ~0,
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4
}
Byłem trochę zaskoczony, widząc to, więc próbowałem go skompilować i zadziałało... ale ja nadal Nie wiem, co to znaczy/robi. Jakaś pomoc??
10 answers
~ jest unarnym operatorem dopełniacza -- odwraca bity swojego operandu.
~0 = 0xFFFFFFFF = -1
W arytmetyce dopełniacza dwójki, ~x == -x-1
Operator ~ można znaleźć w prawie każdym języku, który zapożyczył składnię z C, w tym Objective-C / C++/C#/Java / Javascript.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-29 14:35:28
Myślę, że:
[Flags]
public enum PurchaseMethod
{
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4,
All = Cash | Check | CreditCard
}
Byłoby bardziej jasne.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-22 21:42:59
public enum PurchaseMethod
{
All = ~0, // all bits of All are 1. the ~ operator just inverts bits
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4
}
Z powodu dwóch dopełnień w C#, ~0 == -1
, liczba, w której wszystkie bity są 1 w reprezentacji binarnej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-22 21:47:33
Its better than the
All = Cash | Check | CreditCard
Rozwiązanie, bo jeśli dodasz później inną metodę, powiedz:
PayPal = 8 ,
Będziesz już gotowy z tyldą-All, ale musisz zmienić wszystkie linie z innymi. Więc jest mniej podatny na błędy później.
Pozdrawiam
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-22 22:38:03
Tylko na marginesie, gdy używasz
All = Cash | Check | CreditCard
Masz dodatkową korzyść, która Cash | Check | CreditCard
oceniłaby na All
, a nie na inną wartość (-1), która nie jest równa wszystkim, a zawiera wszystkie wartości.
Na przykład, jeśli użyjesz trzech pól wyboru w interfejsie
[] Cash
[] Check
[] CreditCard
I zsumować ich wartości, a użytkownik wybierze je wszystkie, zobaczysz All
w wynikowym enum.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-22 23:00:36
Dla innych, którzy uznali to pytanie za pouczające, mam szybki przykład do podzielenia się. Poniższy fragment z implementacji metody malowania, jak opisano w tej dokumentacji Mono , wykorzystuje ~
do wspaniałego efektu:
PaintCells (clipBounds,
DataGridViewPaintParts.All & ~DataGridViewPaintParts.SelectionBackground);
Bez operatora ~
kod prawdopodobnie wyglądałby mniej więcej tak:
PaintCells (clipBounds, DataGridViewPaintParts.Background
| DataGridViewPaintParts.Border
| DataGridViewPaintParts.ContentBackground
| DataGridViewPaintParts.ContentForeground
| DataGridViewPaintParts.ErrorIcon
| DataGridViewPaintParts.Focus);
... ponieważ wyliczenie wygląda tak:
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
}
Zauważyłeś podobieństwo enum do odpowiedzi Seana Brighta?
Myślę, że najważniejsze dla mnie jest to, że ~
jest tym samym operatorem w enum, co w normalnej linii kodu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-22 03:34:06
Jest operatorem dopełniacza, Oto artykuł, do którego często odwołuję się dla operatorów bitowych
Http://www.blackwasp.co.uk/CSharpLogicalBitwiseOps.aspx
Również msdn używa go w swoim artykule enums, który pokazuje, że używa go lepiej
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-22 21:42:52
Alternatywa, której osobiście używam, która robi to samo, co odpowiedź @ Seana Brighta, ale wygląda dla mnie lepiej, to ta:
[Flags]
public enum PurchaseMethod
{
None = 0,
Cash = 1,
Check = 2,
CreditCard = 4,
PayPal = 8,
BitCoin = 16,
All = Cash + Check + CreditCard + PayPal + BitCoin
}
Zauważ, jak binarna natura tych liczb, które są potęgami dwóch, sprawia, że następujące twierdzenie jest prawdziwe: (a + b + c) == (a | b | c)
. I IMHO wygląda lepiej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-21 03:05:03
Przeprowadziłem kilka eksperymentów z ~ i okazało się, że może mieć pułapki. Rozważ ten fragment dla Linqpada, który pokazuje, że wartość all enum nie zachowuje się tak, jak oczekiwano, gdy wszystkie wartości są orowane razem.
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
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-15 13:55:37
Po prostu chcę dodać, jeśli używasz [Flags] enum, wtedy wygodniejsze może być użycie bitowego operatora przesunięcia w lewo, jak to:
[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
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-04 13:09:10