Rozważmy następujący fragment kodu:Enum.Parse powracający nieoczekiwane członkowie
namespace ConsoleApplication1 {
class Program {
public static void Main (string[] args) {
var en = (TestEnum)Enum.Parse(typeof(TestEnum), "AA");
Console.WriteLine(en.ToString());
Console.ReadKey();
}
}
public enum TestEnum {
AA = 0x01,
AB = 0x02,
AC = 0x03,
BA = 0x01,
BB = 0x02,
BC = 0x03
}
}
Jeśli wykonasz to zmienna en
dostanie wartość TestEnum.BA
. Teraz dowiedziałem się z tego, że flagi wyliczające powinny być unikatowe, lub uzyskać takie nieoczekiwane rzeczy, ale nie rozumiem, co się tutaj dzieje.
Jeszcze dziwniejszą częścią jest to, że kiedy dodaję atrybut [Flagi] do TestEnum, rozwiązuje on problem i zwraca TestEnum.AA zamiast TestEnum.BA, ale dla oryginalnego wyliczenia (które jest znacznie większe, około ~ 200 członków), dla których odkryłem ten problem, nie ma to znaczenia.
Rozumiem, że wyliczenia są typem wartości, więc podczas definiowania własnych flag będzie przechowywana wartość w pamięci jako 0x01 w przypadku TestEnum.AA, a po rzutowaniu z obiektu do TestEnum będzie wykonaj wyszukiwanie dla tej wartości flagi i znajdź TestEnum.BA.
Potwierdza to również uruchamiając następującą linię:
var en = (TestEnum)(object)TestEnum.AA;
Console.WriteLine(en.ToString());
który wyjściowa: BA
Więc moje pytanie brzmi: co dokładnie się tu dzieje? I co ważniejsze, dlaczego dodanie atrybutu Flags ma znaczenie?
Ponieważ mają tę samą wartość, wybierze jeden dość dowolnie. [To powiązane pytanie] (https://stackoverflow.com/questions/8043027/non-unique-enum-values) może pomóc. –
Nie znam wewnętrznego działania enumu, więc nie będę próbował tu odpowiadać (będą to zdolniejsze osoby, które potrafią to zrobić), ale w gruncie rzeczy atrybut "[Flagi]" ** tylko ** ma znaczenie na części 'ToString()' (na formatowaniu) ... w przeciwnym razie enum działa dokładnie tak samo – Jcl
Dodanie '[Flagi]' prawdopodobnie po prostu zmienia algorytm używany do określenia poprawnego wartość. Obie odpowiedzi są poprawne. – DavidG