2009-08-10 18 views
8

W Javie, od czasu do czasu rzucam bezpośrednio na numer AssertionError, aby potwierdzić, że konkretna linia nie zostanie osiągnięta. Przykładem tego może być stwierdzenie, że nie można osiągnąć przypadku default w instrukcji switch (patrz np. this JavaSpecialists page).. Netto odpowiednik Java's AssertionError

Chciałbym użyć podobnego mechanizmu w .Net. Czy istnieje równoważny wyjątek, którego mógłbym użyć? Czy istnieje inna metoda, która mogłaby zostać użyta z takim samym efektem?

Edit - W celu wyjaśnienia, szukam mechanizm awarii flagi w czasie wykonywania, w kodzie wydany, aby wskazać, że doszło do (być katastrofalne) awaria jakiegoś niezmiennika w kodzie. Połączony przykład generuje losową liczbę całkowitą z przedziału od 0 do 2 (włącznie) i zapewnia, że ​​wygenerowana liczba zawsze wynosi 0, 1 lub 2. Jeśli to twierdzenie nie jest spełnione, lepiej byłoby całkowicie zatrzymać wykonywanie, zamiast kontynuować z nieznanym uszkodzony stan systemu.

Odpowiedz

8

Zwykle wyrzucam InvalidOperationException lub ArgumentOutOfRangeException zależnie od tego skąd pochodzi wartość.

Alternatywnie istnieje Debug.Assert (które nie tylko wtedy, gdy masz symbol DEBUG preprocesora zdefiniowany) lub w .NET 4.0 można użyć Contract.Fail, Contract.Assert lub Contract.Assume w zależności od sytuacji. Jawnie rzucanie wyjątku ma tę zaletę, że kompilator wie, że następna instrukcja jest nieosiągalna.

Nie jestem wielkim fanem Debug.Assert - zwykle nie nadaje się do wydania (jako że generuje okienko asercji, a nie tylko niepowodzenie) i domyślnie nie zostanie wyzwolone mimo to. Preferuję wyjątki, które są zawsze wyrzucane, ponieważ uniemożliwiają wykonanie kodu bez względu na możliwość wykrycia, że ​​"coś jest nie tak".

Code Contracts nieco zmienia grę, ponieważ istnieje wiele opcji, które zostaną zachowane w czasie wykonywania, a static checker może pomóc udowodnić, że nie wejdziesz w ten stan. Nadal musisz wybrać politykę czasu wykonania ...

1

Możesz użyć metody Trace.Assert, która będzie działać na kompilacjach wydania (jeśli masz zdefiniowany symbol kompilacji TRACE, który jest domyślnie zdefiniowany w projektach Visual Studio) . Możesz także dostosować sposób, w jaki aplikacja reaguje na błędy asercji, za pomocą numeru TraceListener. Wartością domyślną jest (co nie dziwi) wartość DefaultTraceListener, która pokaże potwierdzenie w oknie dialogowym, jeśli aplikacja działa w trybie interaktywnym. Jeśli chcesz rzucić wyjątek, możesz na przykład utworzyć własny TraceListener i wyrzucić go na metodę Fail. Następnie możesz usunąć DefaultTraceListener i użyć własnego, programmatically lub configuration file.

To wygląda na wiele problemów i jest uzasadnione tylko wtedy, gdy chcesz dynamicznie zmieniać sposób, w jaki aplikacja obsługuje asercje za pomocą detektorów śledzenia. W przypadku naruszeń, które zawsze chcesz zawodzić, utwórz własną klasę AssertionException i od razu ją odrzuć.

Dla .NET 4.0 zdecydowanie powinienem przyjrzeć się metodzie Contract.Assert. Ale ta metoda jest kompilowana tylko wtedy, gdy zdefiniowane są symbole DEBUG lub. DEBUG nie będzie działał na wersjach wydania, a CONTRACTS_FULL będzie także włączał wszystkie pozostałe sprawdzanie umów, z których niektóre mogą nie być obecne w kompilacjach wydań.

Powiązane problemy