Kiedy należy używać debugowania.Assert ()?

Jestem profesjonalnym inżynierem oprogramowania od około roku, ukończyłem studia z tytułem CS. O asercjach wiem od jakiegoś czasu w C++ i C, ale do niedawna nie miałem pojęcia, że w ogóle istnieją w C# i. NET.

Nasz kod produkcyjny nie zawiera żadnych twierdzeń i moje pytanie jest takie...

Czy powinienem zacząć używać Asserts w naszym kodzie produkcyjnym? A jeśli tak, to kiedy jego użycie jest najbardziej odpowiednie? Czy bardziej sensowne byłoby Robienie

Debug.Assert(val != null);

Lub

if ( val == null )
    throw new exception();
Author: Even Mien, 2008-09-24

20 answers

W debugowanie aplikacji Microsoft.NET 2.0 John Robbins ma dużą sekcję dotyczącą twierdzeń. Jego główne punkty to:

    / Align = "left" / Nigdy nie można mieć zbyt wielu twierdzeń.
  1. twierdzenia nie zastępują WYJĄTKÓW. Wyjątki obejmują rzeczy, których wymaga kod; twierdzenia obejmują rzeczy, które zakłada.
  2. dobrze napisane twierdzenie może powiedzieć nie tylko, co się stało i gdzie (jak wyjątek), ale dlaczego.
  3. komunikat o wyjątkach często może być cryptic, wymagający pracy wstecz przez kod, aby odtworzyć kontekst, który spowodował błąd. Twierdzenie może zachować stan programu w momencie wystąpienia błędu.
  4. Assertions dublują się jako dokumentacja, mówiąc innym programistom, od jakich domniemanych założeń zależy Twój kod.
  5. okno dialogowe, które pojawia się, gdy twierdzenie nie powiedzie się, pozwala dołączyć debugger do procesu, dzięki czemu można grzebać wokół stosu tak, jakbyś umieścił tam punkt przerwania.

PS: Jeśli podobał Ci się kod Complete, polecam śledzić go z tej książki. Kupiłem go, aby dowiedzieć się o używaniu plików WinDBG i zrzutu, ale pierwsza połowa jest pełna wskazówek, które pomogą uniknąć błędów w pierwszej kolejności.

 215
Author: Rory MacLeod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:47:21

Umieść Debug.Assert() wszędzie w kodzie, gdzie chcesz mieć kontrolę rozsądku, aby zapewnić niezmienniki. Podczas kompilacji Release build (tzn. nie DEBUG stałe kompilatora), wywołania Debug.Assert() zostaną usunięte, aby nie wpływały na wydajność.

Należy nadal wyrzucać wyjątki przed wywołaniem Debug.Assert(). Assert po prostu upewnia się, że wszystko jest zgodnie z oczekiwaniami, podczas gdy wciąż się rozwijasz.

 83
Author: Mark Cidade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-28 05:35:05

From Code Complete

8 Defensywne Programowanie

8.2 twierdzenia

Asercja to kod używany podczas programowania-Zwykle rutynowy lub makro-które pozwala programowi sprawdzić się w trakcie działania. Kiedy twierdzenie jest prawdziwe, co oznacza, że wszystko działa zgodnie z oczekiwaniami. Gdy jest fałszywe, oznacza to, że wykrył nieoczekiwany błąd w kod. Na przykład, jeśli system zakłada, że klient-informacje plik nigdy nie będzie miał ponad 50 000 rekordów, program może zawierać twierdzenie, że liczba rekordów jest mniejsza lub równa do 50 tys. O ile liczba rekordów jest mniejsza lub równa 50 tys. Jeśli napotka więcej niż 50.000 płyt, jednak będzie głośno "twierdzić", że istnieje błąd w programie.

Twierdzenia są szczególnie przydatne w dużych, skomplikowanych programach i w programach o wysokiej niezawodności. Pozwalają programistom na więcej szybko. wypłukać niedopasowane założenia interfejsu, błędy, które wkradają się, gdy kod jest modyfikowany i tak dalej.

Twierdzenie zwykle przyjmuje dwa argumenty: wyrażenie logiczne, które opisuje założenie, które ma być prawdziwe i przesłanie do wyświetl, jeśli nie jest.

(…)

Normalnie, nie chcesz, aby użytkownicy widzieli wiadomości assertion w kod produkcji; twierdzenia są przede wszystkim do wykorzystania w trakcie rozwoju i konserwacji. Twierdzenia są zwykle skompilowany do kodu na czas rozwoju i skompilowany z kodu do produkcji. Podczas rozwoju, twierdzenia wypychają sprzeczne założenia, nieoczekiwane warunki, złe wartości przekazywane do procedur, i tak dalej. Podczas produkcji są kompilowane z kodu tak, aby twierdzenia nie obniżają wydajności systemu.

 46
Author: juan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-09 16:01:14

Użyj twierdzeń do sprawdzania założeń programistycznych i wyjątków do sprawdzania założeń środowiskowych.

 40
Author: Justin R.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:18:33

FWIW ... Uważam, że moje publiczne metody używają wzorca if () { throw; }, aby upewnić się, że metoda jest wywoływana poprawnie. Moje prywatne metody używają Debug.Assert().

Chodzi o to, że z moimi prywatnymi metodami, to ja jestem pod kontrolą, więc jeśli zacznę wywoływać jedną z moich prywatnych metod z błędnymi parametrami, to gdzieś złamię moje własne założenie-nigdy nie powinienem dostać się do tego stanu. W produkcji, te prywatne twierdzenia powinny idealnie być niepotrzebną pracą ponieważ mam utrzymywać swój stan wewnętrzny w stanie poprawnym i spójnym. Kontrast z parametrami podanymi publicznym metodom, które mogą być wywołane przez każdego w czasie wykonywania: nadal muszę wymuszać tam ograniczenia parametrów, rzucając wyjątki.

Dodatkowo, moje metody prywatne mogą nadal wyrzucać wyjątki, jeśli coś nie działa w czasie wykonywania (błąd sieci, Błąd dostępu do danych, złe dane pobrane z usługi innej firmy itp.). Moje twierdzenia są tylko po to, aby upewnić się, że nie złamałem własne wewnętrzne założenia dotyczące stanu obiektu.

 39
Author: Nicholas Piasecki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-17 15:48:58

Na Twoim miejscu zrobiłbym:

Debug.Assert(val != null);
if ( val == null )
    throw new exception();

Lub w celu uniknięcia wielokrotnego sprawdzania stanu

if ( val == null )
{
    Debug.Assert(false,"breakpoint if val== null");
    throw new exception();
}
 32
Author: Mark Ingram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-04 10:23:19

Jeśli chcesz mieć Asserts w swoim kodzie produkcyjnym (np. Release builds), możesz użyć Trace.Assert zamiast Debug./ Align = "left" /

To oczywiście dodaje narzut do pliku wykonywalnego produkcji.

Również jeśli aplikacja jest uruchomiona w trybie interfejsu użytkownika, domyślnie zostanie wyświetlone okno dialogowe twierdzenia, co może być nieco niepokojące dla użytkowników.

Możesz nadpisać to zachowanie, usuwając DefaultTraceListener: spójrz na dokumentację dla Trace.Słuchacze w MSDN.

W podsumowaniu,

  • Użyj Debugowania.Aby pomóc w wychwytywaniu błędów w kompilacjach Debugujących.

  • Jeśli użyjesz Trace.Utwórz w trybie interfejsu użytkownika, prawdopodobnie chcesz usunąć DefaultTraceListener, aby uniknąć niepokojących użytkowników.

  • Jeśli testowany warunek jest czymś, z czym Twoja aplikacja nie może sobie poradzić, prawdopodobnie lepiej będzie rzucić wyjątek, aby upewnić się, że wykonanie nie będzie kontynuowane. Należy pamiętać, że użytkownik może zignorować twierdzenie.

 22
Author: Joe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:15:52

Twierdzenia są używane do przechwytywania błędu programisty( użytkownika), a nie Użytkownika. Powinny być używane tylko wtedy, gdy nie ma szans, aby użytkownik mógł spowodować pożar. Jeśli piszesz API, na przykład, asserts nie powinny być używane do sprawdzania, czy argument nie jest null w żadnej metodzie, którą może wywołać użytkownik API. Ale może być użyty w prywatnej metodzie, która nie jest ujawniona jako część twojego API, aby stwierdzić, że Twój kod nigdy nie przekazuje argumentu null, gdy nie powinien.

Zwykle popieram wyjątki nad twierdzeniami, gdy nie jestem pewien.

 21
Author: user19113,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:04:35

W większości nigdy w mojej książce. W zdecydowanej większości przypadków, jeśli chcesz sprawdzić, czy wszystko jest zdrowe, rzucaj, jeśli nie jest.

Nie podoba mi się fakt, że to sprawia, że debug build różni się funkcjonalnie od release build. Jeśli debug assert zawiedzie, ale funkcjonalność działa w wydaniu, to jaki to ma sens? Jeszcze lepiej, gdy aserter już dawno opuścił firmę i nikt nie zna tej części kodu. Następnie musisz zabić trochę swojego czasu odkrywając problem, aby sprawdzić, czy to naprawdę problem, czy nie. Jeśli jest to problem, to dlaczego osoba nie rzuca w pierwszej kolejności?

Dla mnie to sugeruje użycie Debug.Twierdzi, że odkładasz problem na kogoś innego, zajmij się problemem sam. Jeśli coś ma być, a nie jest to rzucać.

Myślę, że są możliwe scenariusze krytyczne dla wydajności, gdzie chcesz zoptymalizować swoje twierdzenia i są tam przydatne, jednak jeszcze nie spotkałem się z takim scenariusz.

 10
Author: Quibblesome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-14 05:19:18

W Skrócie

Asserts są używane do osłon i sprawdzania konstrukcji według ograniczeń umownych, mianowicie:

  • Asserts powinny być przeznaczone tylko do debugowania i kompilacji nieprodukcyjnych. Asserts są zazwyczaj ignorowane przez kompilator w release builds.
  • Asserts może sprawdzić błędy / nieoczekiwane warunki, które są pod kontrolą systemu
  • Nie są mechanizmem walidacji pierwszego wiersza danych wejściowych użytkownika ani reguł biznesowych
  • Asserts powinien Nie być używane do wykrywania nieoczekiwanych warunków środowiskowych (które są poza kontrolą kodu), np. brak pamięci, awaria sieci, awaria bazy danych itp. Chociaż rzadko, należy się spodziewać tych warunków(a kod aplikacji nie może rozwiązać problemów, takich jak awaria sprzętu lub wyczerpanie zasobów). Zazwyczaj wyjątki będą wyrzucane - aplikacja może następnie podjąć działania naprawcze (np. ponowić próbę operacji bazy danych lub sieci, spróbować zwolnić pamięć podręczną) lub przerwać z wdziękiem, jeśli wyjątek nie może być obsługiwany.
  • nieudane twierdzenie powinno być fatalne dla Twojego systemu - tzn. w przeciwieństwie do wyjątku, nie próbuj złapać lub obsłużyć nieudanego Asserts - Twój kod działa na nieoczekiwanym terytorium. Ślady stosu i zrzuty awaryjne można wykorzystać do określenia, co poszło nie tak.

Twierdzenia mają ogromne korzyści:

  • aby pomóc w znalezieniu brakującej walidacji danych wejściowych użytkownika lub błędów w kodzie wyższego poziomu.
  • twierdzenia w baza kodu wyraźnie przekazuje czytelnikowi założenia zawarte w kodzie
  • Assert będzie sprawdzany w trybie runtime w Debug buildach.
  • gdy kod zostanie wyczerpująco przetestowany, przebudowa kodu jako Wydania usunie obciążenie wydajności weryfikacji założenia(ale z tą korzyścią, że późniejsza Kompilacja debugowania zawsze przywróci sprawdzenie, jeśli zajdzie taka potrzeba).

... Więcej Szczegółów

Debug.Assert wyraża warunek, który został przyjęty o stanie przez pozostała część bloku kodu znajduje się pod kontrolą programu. Może to obejmować stan podanych parametrów, stan członków instancji klasy lub to, że zwrot z wywołania metody znajduje się w jej zakontraktowanym / zaprojektowanym zakresie. Zazwyczaj asserts powinien zawiesić wątek / proces / program ze wszystkimi niezbędnymi informacjami (śledzenie stosu, zrzut awaryjny itp.), ponieważ wskazują na obecność błędu lub nieprzewidywalnego warunku, do którego nie został zaprojektowany (tj. awarie asercji), z jednym możliwym wyjątkiem, gdy samo assertion może spowodować więcej szkód niż błąd (np. kontrolerzy ruchu lotniczego nie chcieliby YSOD, gdy samolot przechodzi pod wodę, chociaż nie ma wątpliwości, czy kompilacja debugowania powinna zostać wdrożona do produkcji ...)

Kiedy należy stosować Asserts? - W dowolnym punkcie systemu, API biblioteki lub usługi, w którym dane wejściowe do funkcji lub stanu klasy są uznawane za ważne (np. gdy Walidacja została już dokonana na użytkowniku dane wejściowe w warstwie prezentacji systemu klasy warstwy biznes i warstwy danych zazwyczaj zakładają, że kontrole null, kontrole zakresu, kontrole długości łańcucha itp.na wejściu zostały już wykonane). - Typowe Assert kontrole obejmują, gdzie nieprawidłowe założenie skutkowałoby dereferencją obiektu null, dzielnikiem zerowym, przepełnieniem arytmetyki numerycznej lub daty i ogólnym poza pasmem / nie zaprojektowanym do zachowania (np. jeśli 32-bitowy int został użyty do modelowania wieku człowieka, byłoby rozsądne Assert, aby wiek był w rzeczywistości między 0 a 125 lub tak-wartości -100 i 10^10 nie zostały zaprojektowane).

. Net Code Contracts
W stos.Net, Code Contracts mogą być używane oprócz, lub jako alternatywa dla używając Debug.Assert. Kontrakty kodowe mogą dodatkowo sformalizować sprawdzanie stanu i mogą pomóc w wykrywaniu naruszeń założeń w czasie ~ compile (lub wkrótce potem, jeśli są uruchamiane jako sprawdzenie w tle w IDE).

Design by Contract (DBC) checks dostępne obejmują:

  • Contract.Requires - Warunki Wstępne Umowy
  • Contract.Ensures - Zakontraktowane Warunki Postkontynentalne
  • Invariant - wyraża założenie o stanie obiektu we wszystkich punktach jego żywotności.
  • Contract.Assumes - uspokaja sprawdzanie statyczne w przypadku wywołania metod niestandardowych.
 9
Author: StuartLC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-30 06:35:09

Zgodnie ze standardem IDesign , powinieneś

Potwierdź każde założenie. Średnio co piąta linia jest twierdzeniem.

using System.Diagnostics;

object GetObject()
{...}

object someObject = GetObject();
Debug.Assert(someObject != null);

Jako zastrzeżenie powinienem wspomnieć, że nie znalazłem praktycznego wdrożenia tego IRL. Ale to jest ich standard.

 7
Author: devlord,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 20:04:43

Używaj twierdzeń tylko w przypadkach, gdy chcesz usunąć czek dla kompilacji release. Pamiętaj, że Twoje twierdzenia nie odpalą się, jeśli nie skompilujesz się w trybie debugowania.

Biorąc pod uwagę Twój przykład check-for-null, jeśli jest to w wewnętrznym API, mogę użyć twierdzenia. Jeśli jest w publicznym API, zdecydowanie użyłbym wyraźnego check and throw.

 6
Author: Derek Park,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:03:56

Wszystkie twierdzenia powinny być kodami, które można zoptymalizować do:

Debug.Assert(true);

Ponieważ sprawdza coś, co już założyłeś, że jest prawdą. Np.:

public static void ConsumeEnumeration<T>(this IEnumerable<T> source)
{
  if(source != null)
    using(var en = source.GetEnumerator())
      RunThroughEnumerator(en);
}
public static T GetFirstAndConsume<T>(this IEnumerable<T> source)
{
  if(source == null)
    throw new ArgumentNullException("source");
  using(var en = source.GetEnumerator())
  {
    if(!en.MoveNext())
      throw new InvalidOperationException("Empty sequence");
    T ret = en.Current;
    RunThroughEnumerator(en);
    return ret;
  }
}
private static void RunThroughEnumerator<T>(IEnumerator<T> en)
{
  Debug.Assert(en != null);
  while(en.MoveNext());
}

W powyższym przykładzie, istnieją trzy różne podejścia do parametrów null. Pierwszy akceptuje go jako dopuszczalny(po prostu nic nie robi). Drugi rzuca wyjątek dla kodu wywołującego do obsługi (lub nie, powodując komunikat o błędzie). Trzeci zakłada, że to niemożliwe i twierdzi, że tak jest.

W pierwsza sprawa, nie ma problemu.

W drugim przypadku jest problem z kodem wywołującym-nie powinien wywoływać {[2] } Z null, więc odzyskuje wyjątek.

W trzecim przypadku, jest problem z tym kodem, ponieważ powinno być już sprawdzone, że en != null zanim został wywołany, tak, że to nieprawda jest błąd. Innymi słowy, powinien to być kod, który teoretycznie można zoptymalizować do Debug.Assert(true), sicne en != null powinno być zawsze true!

 6
Author: Jon Hanna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-29 22:43:55

Pomyślałem, że dodam jeszcze cztery przypadki, w których debuguje.Assert może być właściwym wyborem.

1) coś, czego tu nie widziałem, to dodatkowy koncepcyjny zasięg, który może zapewnić podczas automatycznych testów . Jako prosty przykład:

Gdy jakiś rozmówca wyższego poziomu jest modyfikowany przez autora, który uważa, że rozszerzył zakres kodu, aby obsłużyć dodatkowe scenariusze, najlepiej (!) napiszą testy jednostkowe, aby pokryć ten nowy warunek. Może wtedy być, że w pełni zintegrowany kod wydaje się działać dobrze.

Jednak w rzeczywistości wprowadzono subtelną wadę, ale nie wykrytą w wynikach testów. Callee stało się w tym przypadku niedeterministyczne i tylko dzieje się , aby dostarczyć oczekiwany wynik. A może to spowodowało błąd zaokrąglenia, który był niezauważony. Lub spowodował błąd, który został równoważony w równym stopniu gdzie indziej. Lub przyznano nie tylko żądany dostęp, ale również dodatkowe przywileje, których nie należy przyznawać. Itd.

W tym momencie, debugowanie.Twierdzenia Assert() zawarte w callee połączone z new case (lub edge case) napędzane testami jednostkowymi mogą dostarczyć bezcennego powiadomienia podczas testu, że pierwotne założenia autora zostały unieważnione, a kod nie powinien zostać wydany bez dodatkowej recenzji. Asserts z testami jednostkowymi są idealnymi partnerami.

2) dodatkowo, niektóre testy są proste do napisania, ale kosztowne i niepotrzebne, biorąc pod uwagę początkowe założenia . Na przykład:

Jeśli do obiektu można uzyskać dostęp tylko z pewnego zabezpieczonego punktu wejścia, czy należy wykonać dodatkowe zapytanie do bazy danych praw sieciowych z każdej metody obiektu, aby upewnić się, że wywołujący ma uprawnienia? Na pewno nie. Być może idealnym rozwiązaniem jest buforowanie lub inne rozszerzenie funkcji, ale projekt tego nie wymaga. Debugowanie.Assert () natychmiast pokaże, kiedy obiekt został dołączony do niebezpiecznego punktu wejścia.

3) następny, w niektórych przypadkach produkt może nie mieć pomocnej interakcji diagnostycznej dla wszystkich lub części swoich operacji, gdy jest wdrożony w trybie release. Na przykład:

Załóżmy, że jest to wbudowane urządzenie czasu rzeczywistego. Rzucanie wyjątków i ponowne uruchamianie gdy napotka wadliwy Pakiet jest przeciwne do wydajności. Zamiast tego urządzenie może korzystać z najbardziej wymagającej pracy, nawet do momentu generowania szumów na jego wyjściu. Może również nie mieć interfejsu człowieka, urządzenia rejestrującego, a nawet być fizycznie dostępne dla człowieka w ogóle po wdrożeniu w trybie release, a świadomość błędów jest najlepiej zapewniona poprzez ocenę tego samego wyniku. W tym przypadku liberalne twierdzenia i dokładne testy przedpremierowe są cenniejsze niż wyjątki.

4) wreszcie, niektóre testy są niezauważalne tylko dlatego, że callee jest postrzegane jako niezwykle wiarygodne . W większości przypadków, im kod jest bardziej wielokrotnego użytku, tym więcej wysiłku wkładano w uczynienie go niezawodnym. Dlatego powszechne jest wyjątek dla nieoczekiwane parametry wywołujące, ale sprawdzają nieoczekiwane wyniki wywołujące. Na przykład:

Jeśli operacja core String.Find stwierdzi, że zwróci -1 gdy kryteria wyszukiwania nie zostaną znalezione, możesz być w stanie bezpiecznie wykonać jedną operację, a nie trzy. Jednakże, jeśli rzeczywiście zwrócił -2, możesz nie mieć rozsądnego sposobu działania. Byłoby nieprzydatne zastąpienie prostszego obliczenia takim, który testuje oddzielnie dla -1 wartości, i nieuzasadnione w większości wersji środowiska do zaśmiecania kodu testami zapewniającymi, że podstawowe biblioteki działają zgodnie z oczekiwaniami. W tym przypadku twierdzenia są idealne.

 4
Author: shannon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-26 06:40:45

Cytat zaczerpnięty z pragmatyczny programista: od czeladnika do mistrza

Leave Assertions On

Istnieje powszechne nieporozumienie co do twierdzeń, głoszonych przez ludzi piszących kompilatory i środowiska językowe. It goes coś takiego:

Asercje dodają trochę narzutu do kodu. Bo sprawdzają rzeczy to nigdy nie powinno się zdarzyć, zostaną wywołane tylko przez błąd w kod. Gdy kod ma zostały przetestowane i wysłane, nie są już potrzebne i powinny być wyłączone, aby Kod działał szybciej. Asercje są narzędziem debugowania.

Są tu dwa ewidentnie błędne założenia. Po pierwsze, zakładają, że testy wykrywają wszystkie błędy. W rzeczywistości, dla każdego złożonego programu można są mało prawdopodobne, aby przetestować nawet niewielki procent permutacji Twój kod zostanie wprowadzony (zobacz bezwzględne testowanie).

Po drugie, optymiści zapominają, że Twój program działa w niebezpieczny świat. Podczas testów szczury prawdopodobnie nie będą gryzły przez kabel komunikacyjny, ktoś grający w grę nie wyczerpie pamięci i pliki dziennika nie wypełnią dysku twardego. Takie rzeczy mogą się zdarzyć, gdy Twój program działa w środowisku produkcyjnym. Twoja pierwsza linia obrona sprawdza ewentualne błędy, a twój drugi używa twierdzenia, aby spróbować wykryć te, które przegapiłeś.

Wyłączanie asercji podczas dostarczania programu do produkcja jest jak przekroczenie wysokiego drutu bez siatki, bo kiedyś udało Ci się w praktyce. Jest dramatyczna wartość, ale trudno o życie ubezpieczenie.

Nawet jeśli masz problemy z wydajnością, Wyłącz Tylko te twierdzenia, które naprawdę cię uderzyły .

 4
Author: Teoman shipahi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 00:02:51

Należy zawsze używać drugiego podejścia (rzucanie WYJĄTKÓW).

Również jeśli jesteś w produkcji (i masz release-build), lepiej wyrzucić wyjątek (i pozwolić aplikacji zawiesić się w najgorszym przypadku) niż pracować z nieprawidłowymi wartościami i może zniszczyć dane Klienta(co może kosztować tysiące dolarów).

 2
Author: Thomas Danecker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:09:30

Powinieneś użyć debugowania.Assert do testowania błędów logicznych w swoich programach. Kompilator może informować tylko o błędach składniowych. Należy więc zdecydowanie używać instrukcji Assert do testowania błędów logicznych. Jak np. testowanie programu sprzedającego samochody, które tylko BMWs są niebieskie powinny otrzymać 15% zniżki. Kompilator nie powie Ci nic o tym, czy twój program jest logicznie poprawny w wykonywaniu tego, ale stwierdzenie assert może.

 0
Author: orlando calresian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:03:40

Przeczytałem tutaj odpowiedzi i pomyślałem, że powinienem dodać ważne rozróżnienie. Istnieją dwa bardzo różne sposoby wykorzystania twierdzeń. Jednym z nich jest tymczasowy Skrót programistyczny "to naprawdę nie powinno się zdarzyć, więc jeśli to da mi znać, abym mógł zdecydować, co zrobić", coś w rodzaju warunkowego punktu przerwania, w przypadkach, w których Twój program jest w stanie kontynuować. Drugi, to sposób na umieszczenie założeń dotyczących poprawnych Stanów programu w kodzie.

W pierwszym przypadku, twierdzenia nie muszą nawet znajdować się w kodzie końcowym. Powinieneś używać Debug.Assert podczas tworzenia i możesz je usunąć, jeśli / kiedy nie są już potrzebne. Jeśli chcesz je zostawić lub jeśli zapomnisz je usunąć, nie ma problemu, ponieważ nie będą miały żadnego wpływu na Kompilacje wydań.

Ale w drugim przypadku, twierdzenia są częścią Kodeksu. Oni, cóż, twierdzą, że twoje założenia są prawdziwe, a także je dokumentują. W takim razie, naprawdę chcesz zostawić je w kodzie. Jeśli program jest w stanie nieważnym nie powinno być dozwolone kontynuowanie. Gdybyś nie mógł sobie pozwolić na hit wydajności nie używałbyś C#. Z jednej strony przydatne może być dołączenie debuggera, jeśli tak się stanie. Z drugiej strony nie chcesz, aby ślad stosu pojawiał się na Twoich użytkownikach, a co ważniejsze, nie chcesz, aby mogli go zignorować. Poza tym, jeśli jest w serwisie, zawsze będzie ignorowany. Dlatego w produkcji poprawnym zachowaniem byłoby wyrzucenie wyjątku i użycie normalna obsługa wyjątków Twojego programu, która może pokazać użytkownikowi ładną wiadomość i zapisać szczegóły.

Trace.Assert ma doskonały sposób, aby to osiągnąć. Nie zostanie on usunięty podczas produkcji i może być skonfigurowany z różnymi słuchaczami za pomocą aplikacji.config. Więc dla rozwoju domyślna obsługa jest w porządku, a dla produkcji można utworzyć prosty TraceListener jak poniżej, który rzuca wyjątek i aktywować go w pliku konfiguracyjnym produkcji.

using System.Diagnostics;

public class ExceptionTraceListener : DefaultTraceListener
{
    [DebuggerStepThrough]
    public override void Fail(string message, string detailMessage)
    {
        throw new AssertException(message);
    }
}

public class AssertException : Exception
{
    public AssertException(string message) : base(message) { }
}

Oraz w konfiguracji produkcyjnej plik:

<system.diagnostics>
  <trace>
    <listeners>
      <remove name="Default"/>
      <add name="ExceptionListener" type="Namespace.ExceptionTraceListener,AssemblyName"/>
    </listeners>
  </trace>
 </system.diagnostics>
 0
Author: AlexDev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-22 13:29:41

Nie wiem jak to jest w C # i. NET, ale w C assert() działa tylko wtedy, gdy jest skompilowane z-DDEBUG - użytkownik końcowy nigdy nie zobaczy assert() jeśli jest skompilowane bez. Tylko dla deweloperów. Używam go bardzo często, czasami łatwiej jest śledzić błędy.

 -1
Author: unexist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:00:12

Nie użyłbym ich w kodzie produkcyjnym. Wyrzuć wyjątki, Złap i zaloguj.

Również trzeba uważać w asp.net, jako assert może pojawić się na konsoli i zamrozić żądanie(żądania).

 -1
Author: mattlant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 19:00:58