Enumeracja – wartość domyślna
Pracując w świecie .NET-a często korzystam z typu wyliczeniowego. Enumeracje stosujemy wszędzie tam, gdzie chcemy zwracać wartości, gdzie każda z nich ma jakieś znaczenie. Czyż nie łatwiej jest zapisać typ wyliczeniowy i później zwrócić go, aniżeli zwracać jakieś liczbowe wartości i następnie je tłumaczyć ? Często nie myślimy co pod tym typem wyliczeniowym się znajduje. A co się tam znajduje ? Otóż, jeśli nie podamy jawnie jakiego typu wewnętrznego ma być nasz typ wyliczeniowy, to będzie on opakowanym int-em. I właśnie z typem wewnętrznym związany jest problem, o którym chciałbym dzisiaj opowiedzieć.
Enum wartość domyślna
Jak wiemy, w czasie inicjalizacji zmiennej typu value object nadawana jest im wartość, co może być dla źle skonstruowanych typów wyliczeniowych problemem. Do rzeczy, mieliśmy w projekcie model danych, gdzie jedną z właściwości był właśnie typ wyliczeniowy. Oczywiście w momencie tworzenia takiego modelu wszystkie wartości w nim zawarte miały wartości domyślne. Poszczególne właściwości w modelu były wypełniane danymi. Aż tu nagle nie działa, dostajemy informacje, że wartość wyliczenia jest zawsze taka sama. O ironio, była to zakładana wartość, jeśli wszystko działało prawidłowo.
Przejdźmy do naszego przykładowego kodu :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
public enum State { Ok, Hold, Restarting, NotResponding } public class DtoClass { public State State { get; set; } public string Name { get; set; } } class Program { static void Main(string[] args) { var data = new DtoClass(); data.Name = "alex"; // data.State = State.NotResponding; Console.WriteLine($"Name: {data.Name}, State: {data.State}"); Console.ReadLine(); } } |
Jak widzimy mamy tutaj przykładowy typ wyliczeniowy “State”. Prostą klasę “DtoClass” oraz program przedstawiający nasz niefortunny błąd. Powodem naszego problemu był brak przypisania właściwości State w klasie dto (brak przypisania podobnego do tego w linii 21). Widzicie już o co mi chodzi ? W tym przypadku zawsze dostaniemy spodziewany stan Ok, co może być naprawdę ciężko odnaleźć w produkcyjnym kodzie.
Co z tym można zrobić? To akurat jest proste i sprowadza się do dodania naszej własnej wartości domyślnej dla takiego typu wyliczeniowego. Dodając do powyższego stan Unknown jako pierwszy lub nawet z jawnie podaną wartością ułatwiłby pracę oraz analizę problemu. No cóż, każdy z nas uczy się na błędach. Ważne tylko, ażeby uczyć się na cudzych. A ty czytelniku ile masz niebezpiecznych enumów, które tylko czekają na to, aby się ujawnić ?
A czy nie lepiej zamiast dodawania dodatkowego statusu po prostu wymusić jak ma być reprezentowany i nadać wartość pierwszemu statusowi? Implementacja State wyglądałaby następująco:
public enum State
{
Ok = 1,
Hold,
Restarting,
NotResponding
}
Dzięki takiej zmianie nie musisz zmieniać już istniejącej implementacji i testów.
Tak również nie musisz. Poprostu pierwszym elementem będzie Unknown który prawdopodobnie nigdy nie powinien się znaleźć w działającej aplikacji. Rozwiązanie w Unknown moim zdaniem jest również lepsze jeśli chodzi o debugowanie gdyż przy podglądzie zmiennej dostajemy nasz status zamiast 0, ale to prawdopodobnie jest bardzo indywidualne.
Hej wielkie dzięki za post !
Hej dzięki za wpis !