Jeśli używam instrukcji switch do obsługi wartości z wyliczenia (który jest własnością mojej klasy) i mam wielkość liter dla każdej możliwej wartości - czy warto dodać kod do obsługi wielkości „domyślnej”?
enum MyEnum
{
MyFoo,
MyBar,
MyBat
}
MyEnum myEnum = GetMyEnum();
switch (myEnum)
{
case MyFoo:
DoFoo();
break;
case MyBar:
DoBar();
break;
case MyBat:
DoBat();
break;
default:
Log("Unexpected value");
throw new ArgumentException()
}
Nie sądzę, że dzieje się tak, ponieważ tego kodu nigdy nie można osiągnąć (nawet przy testach jednostkowych). Mój współpracownik nie zgadza się i uważa, że to chroni nas przed nieoczekiwanym zachowaniem spowodowanym dodaniem nowych wartości do MyEnum.
Co mówisz, społeczność?
MyEnum
a następnie przekaże ją za pomocą przełącznika?switch
całkowicie eliminując tę instrukcję.Odpowiedzi:
Dołączenie domyślnego przypadku nie zmienia sposobu działania kodu, ale sprawia, że jest on łatwiejszy w utrzymaniu. Robiąc kod w sposób oczywisty (loguj wiadomość i zgłaszaj wyjątek), dołączasz dużą czerwoną strzałkę dla stażysty, którego firma zatrudni w lecie, aby dodać kilka funkcji. Strzałka mówi: „Hej, ty! Tak, rozmawiam z WAMI! Jeśli zamierzasz dodać kolejną wartość do wyliczenia, lepiej tu też wstaw skrzynkę”. Ten dodatkowy wysiłek może dodać kilka bajtów do skompilowanego programu, co należy rozważyć. Ale uratuje to także kogoś (może nawet ciebie w przyszłości) gdzieś pomiędzy godziną a dniem bezproduktywnego drapania głowy.
Aktualizacja: Sytuacja opisana powyżej, tj. Ochrona przed wartościami dodanymi do wyliczenia w późniejszym czasie, może zostać przechwycona przez kompilator. Clang (i gcc, jak sądzę) domyślnie wyświetli ostrzeżenie, jeśli włączysz typ wyliczeniowy, ale nie masz przypadku obejmującego każdą możliwą wartość w wyliczeniu. Na przykład, jeśli usuniesz
default
skrzynkę z przełącznika i dodasz nową wartośćMyBaz
do wyliczenia, otrzymasz ostrzeżenie:Pozwolenie kompilatorowi na wykrycie odkrytych przypadków polega na tym, że w dużej mierze eliminuje potrzebę tej nieosiągalnej
default
sprawy, która przede wszystkim zainspirowała twoje pytanie.źródło
Rozmawiałem dziś rano również ze współpracownikiem - to naprawdę niefortunne, ale myślę, że obchodzenie się z ustawieniem domyślnym jest wymagane ze względów bezpieczeństwa z dwóch powodów:
Po pierwsze, jak wspomina współpracownik, kod zabezpiecza kod przed dodaniem nowych wartości do wyliczenia. Może się to wydawać lub nie, ale zawsze istnieje.
Co ważniejsze, w zależności od języka / kompilatora może istnieć możliwość posiadania wartości, które nie są członkami wyliczenia w zmiennej przełączanej. Na przykład w języku C #:
Dodając prosty
case default:
i rzucając wyjątek, uchroniłeś się przed tym dziwnym przypadkiem, w którym „nic” się nie dzieje, ale „coś” powinno się zdarzyć.Niestety, w zasadzie za każdym razem, gdy piszę instrukcję switch, to dlatego, że sprawdzam przypadki wyliczenia. Naprawdę chciałbym, aby zachowanie „domyślnie wyrzucać” mogło być wymuszone przez sam język (przynajmniej przez dodanie słowa kluczowego).
źródło
Dodanie skrzynki domyślnej, nawet jeśli nie spodziewasz się jej osiągnąć, może być dobrą rzeczą. Ułatwi to debugowanie, jeśli Twój kod od razu zgłasza wyjątek „To nie powinno się zdarzyć”, a nie później w programie, wywołując tajemniczy wyjątek lub zwracając nieoczekiwane wyniki bez błędów.
źródło
Mówię:
Spróbuj dodać inny typ do
MyEnum
. Następnie zmień ten wiersz:do
Następnie uruchom kod z domyślną wielkością liter i bez domyślnej wielkości liter. Które zachowanie preferujesz?
Posiadanie domyślnej wielkości liter może być również przydatne do wychwytywania
NULL
wartości i zapobieganiaNullPointerExceptions
.źródło
Jeśli masz pomysł, jak zaoszczędzić czas mach, nalegając na domyślny przypadek, nie musisz zadawać pytania. Ciche nie robienie niczego w przypadku błędu jest nie do przyjęcia - czy po cichu wychwytujesz wyjątki, które nigdy nie powinny się zdarzyć? Pozostawienie „kopalni” dla programistów, którzy podążają za tobą, jest również niedopuszczalne.
Jeśli Twój kod nigdy nie będzie zmieniany ani modyfikowany i jest w 100% wolny od błędów, pominięcie domyślnej wielkości może być OK.
Ada (dziadek solidnych języków programowania) nie skompiluje przełącznika na wyliczeniu, chyba że wszystkie wyliczenia są pokryte lub istnieje domyślny moduł obsługi - ta funkcja jest na mojej liście życzeń dla każdego języka. Nasz standard kodowania Ada stwierdza, że przy włączonych wyliczeniach jawna obsługa wszystkich wartości bez domyślnego ustawienia jest preferowanym sposobem radzenia sobie z tą sytuacją.
źródło