Zawsze jestem 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 poszukać tego w Internecie, ale użycie „~” w wyszukiwaniu nie działa tak dobrze i nie znalazłem również niczego w MSDN (nie mówiąc, że go tam 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, że to zobaczyłem, więc próbowałem to skompilować i zadziałało ... ale nadal nie wiem, co to znaczy / robi. Jakaś pomoc??
c#
enums
language-features
enumeration
Hugoware
źródło
źródło
Odpowiedzi:
~ jest jednoargumentowym operatorem dopełniacza jedynki - odwraca bity swojego operandu.
w arytmetyce uzupełnień do dwóch,
~x == -x-1
operator ~ można znaleźć w prawie każdym języku, który zapożyczył składnię z C, w tym w Objective-C / C ++ / C # / Java / Javascript.
źródło
Myślę, że:
Byłoby trochę bardziej jasne.
źródło
Z powodu dwóch uzupełnień w C #,
~0 == -1
liczba, w której wszystkie bity mają wartość 1 w reprezentacji binarnej.źródło
Jest lepszy niż
rozwiązanie, ponieważ jeśli później dodasz inną metodę, powiedz:
skończysz już z tyldą-All, ale musisz zmienić linię all-line z drugą. Więc później jest mniej podatny na błędy.
pozdrowienia
źródło
Tylko uwaga na marginesie, kiedy używasz
masz dodatkową korzyść, która
Cash | Check | CreditCard
byłaby szacowana naAll
inną wartość (-1), a nie na inną wartość (-1), która nie jest równa all, ale zawiera wszystkie wartości. Na przykład, jeśli używasz trzech pól wyboru w interfejsie użytkownikai zsumuj ich wartości, a użytkownik wybierze je wszystkie, zobaczysz
All
w wynikowym wyliczeniu.źródło
myEnum.HasFlag()
zamiast tego używasz : DAll.HasFlag(Cash | Check | CreditCard)
a to będzie ewaluować jako prawda. Byłoby obejściem, ponieważ==
nie zawsze działa z ~ 0.ToString
nie o używaniu== All
.Dla innych, którzy uznali to pytanie za pouczające, mam szybki
~
przykład do udostępnienia. Poniższy fragment z implementacji metody malowania, jak opisano szczegółowo w tej dokumentacji Mono , wykorzystuje~
z doskonałym efektem:Bez
~
operatora kod prawdopodobnie wyglądałby mniej więcej tak:... bo wyliczenie wygląda tak:
Zwróć uwagę na podobieństwo tego wyliczenia do odpowiedzi Seana Brighta?
Myślę, że najważniejszym dla mnie wnioskiem jest to, że
~
jest to ten sam operator w wyliczeniu, co w normalnym wierszu kodu.źródło
&
być|
s?To operator dopełniacza. Oto artykuł, do którego często odwołuję się w przypadku operatorów bitowych
http://www.blackwasp.co.uk/CSharpLogicalBitwiseOps.aspx
Również msdn używa go w swoim artykule wyliczeń, który pokazuje, że lepiej go używać
http://msdn.microsoft.com/en-us/library/cc138362.aspx
źródło
Alternatywą, której osobiście używam, a która robi to samo, co odpowiedź @Sean Bright, ale dla mnie wygląda lepiej, jest ta:
Wskazówki jak binarny charakter tych liczb, które są potęgami dwójki, wydaje następujące twierdzenie prawdziwe:
(a + b + c) == (a | b | c)
. I IMHO,+
wygląda lepiej.źródło
Poeksperymentowałem z ~ i stwierdziłem, że może mieć pułapki. Rozważmy ten fragment kodu LINQPad, który pokazuje, że wartość wyliczenia All nie zachowuje się zgodnie z oczekiwaniami, gdy wszystkie wartości są razem.
źródło
Po prostu chcę dodać, jeśli używasz wyliczenia [Flags], wygodniejsze może być użycie bitowego operatora przesunięcia w lewo, na przykład:
źródło