zbyt długo na komentarz:
Właściwie atrybut [Flags]
nie zmienia semantyki enum jest w ogóle, to najbardziej powszechnie stosowane metodą ToString
emitować serię nazw zamiast numeru do łącznej wartości .
Załóżmy, że Twój enum został uznany za tak (bez atrybutu Flags
):
enum TicketStatus
{
Created = 1,
Transferred = 2,
Sold = 4
}
Można nadal łączyć różne elementy i wykonywać żadnych działań arytmetycznych, które odnoszą się do Flags ENUM:
TicketStatus status = TicketStatus.Created | TicketStatus.Transferred;
Jednak poniższe zostaną wydrukowane: 3
:
Console.WriteLine(status);
Ale jeśli dodasz atrybut [Flags]
, wydrukuje on Created, Transferred
.
Ponadto, ważne jest, aby pamiętać, że przez TicketStatus.Created | TicketStatus.Transferred
jesteś naprawdę robi bitowego OR
na podstawowej wartości całkowitej, zauważyć, jak w naszym przykładzie, że przypisane wartości są jednoznacznie łączyć:
Created : 0001
Transferred: 0010
Sold: 0100
Dlatego wartość z 3
można jednoznacznie określić jako kombinację Created
i Transferred
.Jednak gdybyśmy mieli to:
enum TicketStatus
{
Created = 1, // 0001
Transferred = 2, // 0010
Sold = 3, // 0011
}
Jak to jest oczywiste, przez reprezentacje binarne, łącząc wartości i sprawdzanie przeciwko członkom jest problematyczne jako połączone elementy mogą być niejednoznaczne. na przykład co to jest status
tutaj?
status = TicketStatus.Created | TicketStatus.Transferred;
Czy Created, Transferred
czy jest to naprawdę Sold
? Jednak kompilator nie będzie narzekał, jeśli spróbujesz to zrobić, co może prowadzić do trudnych do zlokalizowania błędów, takich jak twoje, gdzie niektóre sprawdzenia nie działają tak, jak tego oczekujesz, więc musisz zadbać o to, aby definicja była na miejscu bitowe mieszanie i porównywanie.
Na powiązana uwaga, ponieważ Twoja wypowiedź if
jest naprawdę tylko sprawdzenie, czy bilet ma status Created
, niezależnie od ich łączyć z innymi członkami, tutaj jest lepszy sposób, aby sprawdzić, że (.NET> = 4):
status.HasFlag(TicketStatus.Created)
lub (.NET < 4):
(status & TicketStatus.Created) != 0
co do dlaczego enum nie działa zgodnie z oczekiwaniami, to prawie na pewno, bo nie jawnie określić jednoznacznie bitowe wartości łączyć do i ts członkowie (zazwyczaj uprawnienia dwóch).
Jak to jest "TicketStatus"? Czy to jest wyliczenie z atrybutem "[Flags]"? – MarcinJuraszek
Jaka jest wartość 'ticket.Status', gdy się nie powiedzie, ale spodziewasz się, że będzie" true "? –
Interesujące ... jeśli zamienię enum join (np. '(TicketStatus.Created | TicketStatus.Transfered)') wydaje się działać. Bycie wylicznikiem to wyliczenie oparte na flagach "bajtowych", pomyślałbym, że nie miało to znaczenia? .. jakie pomysły? –