Frage

Ich habe seit etwa einem Jahr jetzt ein professioneller Software-Ingenieur gewesen, mit einem CS Grad absolviert zu haben. Ich habe eine Zeit lang in C über Behauptungen bekannt ++ und C, hatte aber keine Ahnung, dass sie existierte in C # und .NET überhaupt bis vor kurzem.

Unser Produktionscode enthält keine behauptet auch immer und meine Frage ist ...

Soll ich beginnen behauptet in unserem Produktionscode verwenden? Und wenn ja, wann ist der Einsatz am besten geeignet? Wäre es sinnvoll zu tun

Debug.Assert(val != null);

oder

if ( val == null )
    throw new exception();
War es hilfreich?

Lösung

Debuggen von Microsoft .NET 2.0 Anwendungen John Robbins einen großen Abschnitt hat auf Behauptungen. Seine wichtigsten Punkte sind:

  1. Behaupten liberal. Man kann nie zu viele Behauptungen.
  2. Assertions ersetzen nicht Ausnahmen. Ausnahmen decken die Dinge, die Ihr Code Anforderungen; Behauptungen decken die Dinge, die sie annimmt.
  3. Eine gut geschriebene Behauptung kann man nicht einfach sagen, was passiert ist und wo (wie eine Ausnahme), aber warum.
  4. Eine Ausnahme Meldung kann oft kryptische sein, die Sie auffordert, rückwärts durch den Code zu arbeiten, um den Kontext zu erstellen, die den Fehler verursacht hat. Eine Behauptung kann den Programmzustand zu dem Zeitpunkt erhält der Fehler aufgetreten ist.
  5. Assertions Doppel als Dokumentation, sagen andere Entwickler, was Annahmen implizierte Code hängt davon ab.
  6. Der Dialog, wenn eine Behauptung erscheint nicht können Sie einen Debugger an den Prozess anhängen, so können Sie rund um den Stapel stecken, als ob Sie dort einen Haltepunkt gesetzt hatte.

PS: Wenn Sie Code Complete gefallen hat, empfehle ich folgende es mit diesem Buch. Ich kaufte es über die Verwendung von WinDBG und Dump-Dateien zu lernen, aber die erste Hälfte mit Spitzen verpackt, um Fehler in erster Linie zu vermeiden.

Andere Tipps

Setzen Sie Debug.Assert() überall in dem Code, wo Sie haben geistige Gesundheit wollen prüft Invarianten zu gewährleisten. Wenn Sie einen Releasebuild kompilieren (das heißt, keine DEBUG Compiler konstant), werden die Anrufe an Debug.Assert() entfernt werden, damit sie nicht die Leistung beeinträchtigen.

Sie sollten noch Ausnahmen werfen, bevor Debug.Assert() aufrufen. Die Assertion nur stellt sicher, dass alles wie erwartet, wenn Sie still zu entwickeln.

Code Complete

  

8 Defensive Programmierung

     

8.2 Assertions

     

Eine Behauptung ist Code, der während der Entwicklung Gängig eine Routine verwendet werden   oder Makro, das ein Programm erlaubt selbst zu überprüfen, wie es läuft. Wenn ein   Behauptung wahr ist, das bedeutet, dass alles wie erwartet funktioniert.   Wenn es falsch ist, bedeutet, dass es einen unerwarteten Fehler in der festgestellt hat   Code. Zum Beispiel geht davon aus, wenn das System, dass ein Kundeninformations   Datei wird nie mehr als 50.000 Datensätze hat, das Programm könnte   eine Assertion enthält, dass die Anzahl der Datensätze ist oder gleich LessThan   bis 50.000. Solange die Anzahl der Datensätze ist kleiner als oder gleich   50.000, wird die Behauptung schweigen. Wenn es trifft mehr als   jedoch 50.000 Datensätze, wird es laut „behaupten“, dass es eine ist   Fehler im Programm.

     

Assertions sind besonders nützlich bei großen, komplizierten Programmen und   in hohen Zuverlässigkeit Programmen. Sie ermöglichen Programmierer schnell mehr   auszuspülen nicht übereinstimmen Schnittstelle Annahmen, Fehler, die sich einschleichen, wenn   Code modifiziert wird, und so weiter.

     

Eine Behauptung dauert in der Regel zwei Argumente: ein boolescher Ausdruck,   beschreibt die Annahme, dass um wahr zu sein und eine Nachricht angenommen hat, auf   angezeigt, wenn dies nicht der Fall.

     

(...)

     

Normalerweise wollen Sie nicht Benutzer Behauptung Nachrichten sehen in   produktionscode; Behauptungen sind in erster Linie für den Einsatz während der Entwicklung   und Wartung. Assertionen sind normalerweise in den kompilierten Code zu   Entwicklungszeit und aus dem Code für die Produktion zusammengestellt. Während   Entwicklung, Behauptungen widersprüchliche Annahmen auszuspülen,   unerwartete Bedingungen, schlechte Werte an Routinen übergeben, und so weiter.   Während der Produktion werden sie aus dem Code kompiliert, so dass die   Behauptungen abbauen Systemleistung nicht.

FWIW ... Ich finde, dass meine öffentlichen Methoden neigen dazu, die if () { throw; } Muster zu verwenden, um sicherzustellen, dass das Verfahren korrekt aufgerufen wird. Meine privaten Methoden sind in der Regel Debug.Assert() verwenden.

Die Idee ist, dass mit meinen privaten Methoden, bin ich derjenige unter Kontrolle, so dass, wenn ich Aufruf einen meiner eigenen Methoden mit Parametern starten, die nicht korrekt sind, dann meine eigene Annahme, ich habe irgendwo gebrochen - ich soll noch nie in diesem Zustand erhalten. In der Produktion behauptet diese privaten idealerweise unnötige Arbeit sein sollte, da soll ich meinen inneren Zustand gültig und konsistent zu halten. Kontrast mit den Parametern gegeben öffentlichen Methoden, die von jedermann zur Laufzeit aufgerufen werden könnte: Ich muss immer noch da Parametereinschränkungen erzwingen, indem Ausnahmen werfen

.

Darüber hinaus können private Methoden noch Ausnahmen werfen, wenn etwas nicht zur Laufzeit (Netzwerkfehler, Datenzugriffsfehler, schlechte Daten von einem Dritten Dienst abgerufen, etc.) funktioniert. Mein behauptet sind nur da, um sicherzustellen, dass ich meine eigenen internen Annahmen über den Zustand des Objekts nicht gebrochen.

Verwenden Sie behauptet Entwickler Annahmen und Ausnahmen prüfen Umwelt Annahmen zu überprüfen.

Wenn ich Sie wäre, würde ich tun:

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

oder wiederholte Zustandsprüfung zu vermeiden

if ( val == null )
{
    Debug.Assert(false,"breakpoint if val== null");
    throw new exception();
}

Wenn Sie Asserts in Ihrem Produktionscode wollen (das heißt Releasebuilds), können Sie Trace.Assert statt Debug.Assert verwenden.

Das ist natürlich fügt Overhead zu Ihrer Produktion ausführbaren Datei.

Auch wenn Ihre Anwendung in User-Interface-Modus ausgeführt wird, wird die Assertion Dialog standardmäßig angezeigt werden, die für die Benutzer ein bisschen irritierend sein kann.

Sie können dieses Verhalten außer Kraft setzen, indem Sie den Default entfernen. Blick in der Dokumentation für Trace.Listeners in MSDN

Insgesamt

  • Mit Debug.Assert zügig Fang Bugs helfen in Debug baut.

  • Wenn Sie Trace.Assert in User-Interface-Modus zu verwenden, möchten Sie wahrscheinlich die Default entfernen Benutzer zu vermeiden befremdlich.

  • Wenn die Bedingung, die Sie testen sind etwas, das Ihr App ist nicht umgehen kann, sind Sie wahrscheinlich besser dran, eine Ausnahme zu werfen, die Ausführung zu gewährleisten, wird nicht fortgesetzt. Beachten Sie, dass ein Benutzer auswählen kann, eine Behauptung zu ignorieren.

Asserts verwendet werden Programmierer (Sie) Fehler zu fangen, nicht Benutzerfehler. Sie sollten nur verwendet werden, wenn es keine Chance, ein Benutzer die assert dazu führen könnte, zu feuern. Wenn Sie eine API schreiben, zum Beispiel behauptet, soll nicht überprüft werden, dass ein Argument in jeder Methode nicht null ist ein API Benutzer nennen könnte. Aber es könnte in einem privaten Verfahren verwendet wird, nicht als Teil Ihrer API ausgesetzt zu behaupten, dass der Code niemals ein Null-Argument übergibt, wenn er nicht sollte.

ich in der Regel Ausnahmen begünstigen über behauptet, wenn ich nicht sicher bin.

Meistens nie in meinem Buch. In der überwiegenden Mehrzahl der Gelegenheiten, wenn Sie wollen, um zu überprüfen, ob alles gesund ist dann auslösen, wenn es nicht ist.

Was ich nicht mag, ist die Tatsache, dass es einen Debug-Build funktionell anders als bei einem Release-Build macht. Wenn eine Debug-Assertion fehlschlägt aber die Funktionalität arbeitet in Release dann wie funktioniert das Sinn? Es ist sogar besser, wenn die Verfechter lange das Unternehmen verlassen haben und niemand weiß, den Code, dass ein Teil. Dann haben Sie einen Teil Ihrer Zeit zu töten, um das Problem zu erforschen, um zu sehen, ob es wirklich ein Problem ist oder nicht. Wenn es ein Problem ist dann, warum ist nicht die Person, an erster Stelle zu werfen?

Für mich dies legt nahe, durch Debug.Asserts verwenden Sie das Problem an jemand anderen sind aufzuschieben, beschäftigen sich mit dem Problem selbst. Wenn etwas soll der Fall sein, und es ist dann nicht werfen.

Ich denke, es möglicherweise Performance kritischen Szenarien sind, wo Sie Ihr behauptet optimieren wollen weg und sie sind es nützlich, aber ich bin noch ein solches Szenario zu begegnen.

Im Kurzen

Asserts sind für Wachen eingesetzt und für Design by Contract Prüfung von Integritätsbedingungen, nämlich:

  • Asserts für Debug sein sollte und nicht-Produktion baut nur. Behauptet werden in der Regel durch den Compiler in Version ignoriert baut.
  • Asserts kann für Fehler / unerwartete Bedingungen prüfen, die in der Steuerung Ihres Systems
  • Asserts ist NICHT ein Mechanismus für die First-Line-Validierung von Benutzereingaben oder Geschäftsregeln
  • Asserts sollte nicht verwendet werden, unerwartete Umweltbedingungen zu erfassen (die außerhalb der Kontrolle des Codes) sind z.B. aus dem Speicher, Netzwerkausfall, Datenbankfehler, usw. Obwohl selten, sind diese Bedingungen nicht zu erwarten (und Ihr App-Code nicht beheben kann Probleme wie Hardware-Fehler oder Ressourcenerschöpfung). Typischerweise werden Ausnahmen ausgelöst -. Ihre Anwendung kann dann entweder Korrekturmaßnahmen ergreifen (zum Beispiel eine Datenbank oder Netzwerk-Operation wiederholen, Versuch im Cache-Speicher freizugeben) oder anmutig abbrechen, wenn die Ausnahme nicht behandelt werden kann,
  • Es sollte ein Fehler bei Assertion an Ihr System tödlich sein - das heißt im Gegensatz zu einer Ausnahme, versuchen Sie nicht und fangen oder nicht Asserts Griff - Ihr Code in unerwarteten Gebiet arbeitet. Stack-Traces und Crash-Dumps können verwendet werden, um zu bestimmen, was falsch gelaufen ist.

Assertions haben enorme Vorteile:

  • Zur Unterstützung bei der Suche nach vermissten Validierung von Benutzereingaben oder Upstream-Fehler in Code höherer Ebene.
  • der Code-Basis deutlich vermitteln, die Annahmen in den Code für den Leser gemacht Asserts in
  • wird Assert zur Laufzeit in Debug baut geprüft werden.
  • Sobald Code umfassend getestet wurde, wird der Code als Release Wiederaufbau der Leistungsaufwand zur Überprüfung der Annahme entfernen (aber mit dem Vorteil, dass ein später Debug Build immer die Kontrollen zurückkommen, falls erforderlich).

... Mehr Details

Debug.Assert drückt eine Bedingung, die durch den Rest des Codeblocks innerhalb der Steuerung des Programms über Zustand angenommen wurde. Dies kann den Zustand des vorgesehenen Parameters Zustand von Mitgliedern einer Klasseninstanz umfassen, oder dass die Rückkehr von einem Verfahrensaufruf in seinem kontrahierten / konzipierte Bereich liegt. Typischerweise behauptet, soll den Thread / Prozess / Programm mit allen notwendigen Informationen zum Absturz (Stack-Trace, Absturzabbild, usw.), da sie das Vorhandensein eines Fehlers oder unberücksichtigten Zustandes angeben, die für nicht ausgelegt wurde (dh nicht versuchen und zu fangen oder Assertionsfehler), mit einer möglichen Ausnahme von handhaben, wenn eine Behauptung selbst mehr Schaden als die Fehler verursachen könnte (zB Fluglotsen würde kein YSOD will, wenn ein Flugzeug U-Boot geht, obwohl es fraglich ist, ob ein Debug-Build soll eingesetzt werden Produktion ...)

Wann sollten Sie Asserts? verwenden  - An jedem Punkt in einem System oder eine Bibliothek API oder Dienst, wo die Eingaben in einer Funktion oder Zustand einer Klasse gültig (zB angenommen, wenn hat die Validierung bereits auf der Benutzereingabe in der Präsentationsschicht eines Systems durchgeführt worden, das Unternehmen und Datenebene Klassen nehmen typischerweise, dass null Kontrollen, Bereichsprüfungen, Stringlänge Prüfungen usw. auf Eingabe bereits geschehen).  - Gemeinsame Assert Kontrollen umfassen, in denen eine ungültige Annahme in einem Null-Objekt dereferenzieren, ein Nullteiler, numerischen oder Datum arithmetischen Überlauf führen würde, und allgemein aus Band / nicht für das Verhalten ausgelegt (zB wenn ein 32-Bit-int verwendet wurden, ein Mensch ist zu modellieren Alter, wäre es klug, Assert, dass das Alter ist eigentlich zwischen 0 und 125 oder so -. Wert von -100 und 10 ^ 10 wurden nicht für die)

.Net-Code Contracts
In .NET Stapel, -Code Contracts in additiauf, oder als Alternative zu Debug.Assert verwenden. Code Verträge können weitere Zustandsprüfung, formalisieren und bei der Aufdeckung von Verletzungen der Annahmen bei ~ Kompilierung (oder kurz danach, wenn sie als Hintergrundüberprüfung in einer IDE ausgeführt werden) unterstützen können.

Design by Contract (DBC) Kontrollen verfügbar sind:

  • Contract.Requires - Vertraglich Voraussetzungen
  • Contract.Ensures - Vertraglich Nachbedingungen
  • Invariant - äußert eine Annahme über den Zustand eines Objekts an allen Punkten in seiner Lebensdauer
  • .
  • Contract.Assumes - besänftigt den statischen checker, wenn ein Aufruf nicht-Vertrag eingerichtet Methoden hergestellt
  • .

Nach dem IDesign Standard-, sollten Sie

  

Behaupten jede Annahme. Im Durchschnitt ist jede fünfte Zeile eine Behauptung.

using System.Diagnostics;

object GetObject()
{...}

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

Als Haftungsausschluss sollte ich erwähnen, ich habe es nicht praktisch fanden diese IRL umzusetzen. Aber das ist ihr Standard.

Mit Behauptungen nur in Fällen, in denen Sie die Prüfung für die Freigabe entfernt wollen bauen. Denken Sie daran, nicht Ihre Behauptungen feuern, wenn Sie nicht im Debug-Modus kompiliert werden.

Bei der Check-for-null Beispiel, wenn diese in einem internen Nur-API ist, könnte ich eine Behauptung verwenden. Wenn es in einer öffentlichen API ist, würde ich auf jeden Fall die explizite Prüfung nutzen und werfen.

Alle behauptet sollte Code sein, der optimiert werden kann:

Debug.Assert(true);

Weil es etwas ist, überprüft, die Sie bereits angenommen haben, ist wahr. Z.

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());
}

In der oben gibt es drei verschiedene Ansätze Parameter auf null. Die erste nimmt es als zulässig (es gerade tut nichts). Die zweite löst eine Ausnahme für den anrufenden Code zu verarbeiten (oder auch nicht, was zu einer Fehlermeldung). Die dritte nimmt sie kann unmöglich passieren, und behauptet, dass es so ist.

Im ersten Fall gibt es kein Problem.

Im zweiten Fall gibt es ein Problem mit der anrufenden Code -. Es sollte nicht GetFirstAndConsume mit null genannt hat, so wird es eine Ausnahme zurück

Im dritten Fall gibt es ein Problem mit diesem Code, weil es bereits, dass en != null geprüft werden sollte, bevor es überhaupt genannt wurde, so dass es nicht wahr ist, ist ein Fehler. Oder mit anderen Worten, es sollte Code sein, der theoretisch optimiert werden könnte, um Debug.Assert(true), sicne en != null sollte immer true werden!

Ich dachte, ich würde vier weitere Fälle hinzufügen, wo Debug.Assert die richtige Wahl sein kann.

1) Etwas, das ich hier nicht erwähnt gesehen habe, ist die zusätzliche konzeptionelle Abdeckung Asserts während automatisierter Tests zur Verfügung stellen kann. Als einfaches Beispiel:

Wenn einiger höhere Ebene Anrufer von einem Autor geändert wird, der glaubt, sie den Umfang des Codes erweitert hat zusätzliche Szenarien zu behandeln, im Idealfall (!) Sie werden Unit-Tests schreiben diese neue Bedingung zu decken. Es kann dann sein, dass der voll integrierte Code erscheint gut zu funktionieren.

Doch tatsächlich ein subtiler Fehler eingeführt worden, aber nicht in den Testergebnissen festgestellt. Der Angerufene hat sich nicht deterministisch in diesem Fall und nur passiert , um das erwartete Ergebnis zu liefern. Oder vielleicht hat er einen Rundungsfehler ergeben, die unbemerkt war. Oder einen Fehler verursacht, die ebenso an anderer Stelle kompensiert. Oder gewährt nicht nur den Zugang beantragt, aber zusätzliche Privilegien, die nicht gewährt werden sollte. Etc.

An diesem Punkt der Debug.Assert () Aussagen in den Angerufenen enthaltenen gekoppelt mit dem neuen Fall (oder Kantenfall) angetrieben durch Unit-Tests von unschätzbarem Wert Mitteilung während der Prüfung zur Verfügung stellen kann, dass die ursprünglichen Autors Annahmen für ungültig erklärt worden sind, und die Code sollte nicht ohne zusätzliche Überprüfung freigegeben werden. Behauptet mit Unit-Tests sind die perfekten Partner.

2) Zusätzlich einige Tests sind einfach zu schreiben, aber mit hohen Kosten und unnötige den ursprünglichen Annahmen gegeben . Zum Beispiel:

Wenn ein Objekt kann nur von einem bestimmten gesicherten Zugangspunkt zugegriffen werden kann, sollte eine zusätzliche Abfrage an eine Datenbank von jeder Objektmethode Netzwerkrechte vorgenommen wird die Anrufer haben Berechtigungen zu gewährleisten? Sicher nicht. Vielleicht ist die ideale Lösung umfasst Caching oder eine andere Erweiterung der Funktionen, aber das Design sie nicht benötigt wird. Ein Debug.Assert () wird sofort angezeigt, wenn das Objekt zu einem unsicheren Eintrittspunkt angebracht.

3) Als nächstes Ihr in einigen Fällen Produkt nicht hilfreich diagnostische Interaktion für alle oder einen Teil ihrer Tätigkeit haben können, wenn sie in Release-Modus implementiert . Zum Beispiel:

Angenommen, es ist ein Embedded-Echtzeit-Gerät. Werfen Ausnahmen und neu zu starten, wenn sie ein ungültiges Paket begegnet ist kontraproduktiv. Stattdessen kann das Gerät von Best-Effort-Betrieb profitieren, selbst bis zu dem Punkt des Lärm in seiner Ausgabe zu machen. Es kann auch nicht eine menschliche Schnittstelle, Gerät angemeldet hat, oder auch durch menschliche physisch zugänglich sein, überhaupt, wenn im Release-Modus zum Einsatz, und das Bewusstsein für Fehler ist am besten, die von der gleichen Ausgabe der Beurteilung. In diesem Fall sind liberal Assertions und gründliche Prüfung Pre-Release wertvoller als Ausnahmen.

4) Schließlich einige Tests sind unnötigen nur, weil die Angerufene als extrem zuverlässig wahrgenommen wird, . In den meisten Fällen der mehr wiederverwendbare Code, so hat die mehr Mühe gegeben worden es zuverlässig in der Herstellung. Deshalb ist es zu Ausnahmen für unerwartete Parameter von Anrufern häufig, aber Behaupten für unerwartete Ergebnisse aus Aufgerufenen. Zum Beispiel:

Wenn ein Kern String.Find Operation heißt es wird eine -1 zurück, wenn die Suchkriterien nicht gefunden wird, können Sie in der Lage sein, sicher eine Operation auszuführen, anstatt drei. Wenn es jedoch tatsächlich -2 zurückgegeben, können Sie keine vernünftige Vorgehensweise haben. Es wäre nicht hilfreich die einfachere Berechnung mit einer zu ersetzen, die separat für einen -1 Wert testet, und unvernünftig in den meisten Release Umgebungen Wurf Ihres Code mit Tests Core-Bibliotheken zu gewährleisten, wie erwartet funktionieren. ASSERTS In diesem Fall ist ideal.

Quote Genommen von Der Pragmatische Programmierer: Von Geselle Master

  

Lassen Sie Assertions Turned On

     

Es ist ein weit verbreitetes Missverständnis über Behauptungen, verkündet durch   die Menschen, die Compiler und Sprachumgebungen schreiben. Es geht   so etwas wie folgt aus:

     

Assertions fügen Sie einige Overhead-Code. Weil sie prüfen für Dinge   das sollte nie passieren, werden sie nur durch einen Fehler in der ausgelöst werden   Code. Sobald der Code getestet und ausgeliefert wurden, sind sie nicht mehr   erforderlich und sollte ausgeschaltet werden, schneller den Code zum Laufen zu bringen.   Assertions sind eine Debug-Anlage.

     

Es gibt zwei offensichtlich falsche Annahmen hier. Erstens, sie davon ausgehen, dass   Testen findet alle Fehler. In Wirklichkeit für jedes komplexes Programm, das Sie   Es ist unwahrscheinlich, sogar einen winzigen Prozentsatz der Permutationen testen   Ihr Code wird durchgestellt (siehe Ruthless Testing) werden.

     

Zweitens ist die Optimisten vergessen, dass Ihr Programm in einem läuft   gefährliche Welt. Während des Tests werden wahrscheinlich Ratten nagen nicht durch eine   Kommunikationskabel, jemand ein Spiel nicht Speicher erschöpfen, und   Log-Dateien werden nicht auf die Festplatte füllen. Diese Dinge passieren könnte, wenn   Ihr Programm läuft in einer Produktionsumgebung. Ihre erste Linie der   Verteidigung ist die Überprüfung auf eventuelle Fehler und Ihre zweite verwendet   Behauptungen versuchen, diejenigen, die Sie verpasst haben zu erkennen.

     

Behauptungen ausschalten, wenn Sie ein Programm zur Produktion liefern ist   wie ein Hochseil ohne Netz überquert, weil man es einmal gemacht   über in der Praxis . Es gibt dramatischen Wert, aber es ist schwer, das Leben zu erhalten   Versicherung.

     

Auch wenn Sie Performance-Probleme zu tun haben, schalten Sie nur diejenigen   Behauptungen, die Sie wirklich getroffen .

Sie sollten immer den zweiten Ansatz verwenden (werfen Ausnahmen).

Auch wenn Sie in der Produktion sind (und sind eine Release-Build), ist es besser, eine Ausnahme zu werfen (und den App Absturz im schlimmsten Fall lassen) als mit ungültigen Werten zu arbeiten und vielleicht Ihre Kundendaten zerstören (die kosten Tausende von Dollar an).

Sie sollten Debug.Assert verwenden für logische Fehler in Ihren Programmen zu testen. Der Compiler kann Ihnen Syntaxfehler nur informieren. So sollten Sie auf jeden Fall Assert-Anweisungen verwenden, auf logische Fehler zu testen. Wie sagen, ein Programm zu testen, die Autos verkauft, die nur BMWs, die blau sind, sollten einen 15% Rabatt. Die complier konnte man nichts erzählen, wenn Ihr Programm bei der Durchführung dieses logisch korrekt ist, aber eine assert-Anweisung konnte.

Ich habe die Antworten hier gelesen und ich dachte, ich sollte eine wichtige Unterscheidung hinzuzufügen. Es gibt zwei sehr unterschiedliche Weisen, in denen behauptet verwendet werden. Eine davon ist als temporäre Entwickler Abkürzung für „Das sollte wirklich nicht so geschehen, wenn es mich nicht wissen lassen, so kann ich entscheiden, was zu tun ist“, wie eine Art bedingter Haltepunkt, für Fälle, in denen Ihr Programm in der Lage ist, fortzusetzen. Der andere ist ein als eine Möglichkeit, Annahmen über gültige Programmzustände in Ihrem Code zu setzen.

Im ersten Fall ist die Behauptungen müssen nicht einmal in dem endgültigen Code sein. Sie sollten Debug.Assert während der Entwicklung verwenden und Sie können sie, wenn / entfernen, wenn nicht mehr benötigt. Wenn Sie wollen, dass sie verlassen, oder wenn Sie vergessen, sie kein Problem zu entfernen, da sie keine Konsequenzen in Release Compilations haben.

Im zweiten Fall sind die Aussagen sind Teil des Codes. Sie, na ja, behaupten, dass Ihre Annahmen wahr sind, und dokumentieren sie auch. In diesem Fall wollen Sie wirklich in dem Code zu verlassen. Wenn das Programm in einem ungültigen Zustand ist, sollte es nicht fortgesetzt werden. Wenn Sie die Performance-Einbußen leisten können, würden Sie nicht C # verwenden. Einerseits könnte es nützlich sein, um einen Debugger anhängen, wenn es passiert. Auf der anderen Seite wollen Sie nicht die Stack-Trace auf Ihren Benutzern Aufspringen und vielleicht noch wichtiger ist Sie nicht wollen, sie ignorieren können. Außerdem, wenn es in einem Dienst ist wird es immer ignoriert. Daher in der Produktion wäre das richtige Verhalten eine Ausnahme, werfen und die normale Ausnahmebehandlung des Programms verwendet werden, die den Benutzer eine nette Nachricht zeigen könnten und die Details loggen sein.

Trace.Assert hat die perfekte Möglichkeit, dies zu erreichen. Es wird nicht mehr in der Produktion entfernt werden und kann mit verschiedenen Hörern konfiguriert werden app.config. So für die Entwicklung der Standard-Handler ist in Ordnung, und für die Produktion können Sie eine einfache Tracelistener erstellen wie unter denen eine Ausnahme auslöst und aktivieren Sie es in der Produktion config-Datei.

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) { }
}

Und in der Produktion config-Datei:

<system.diagnostics>
  <trace>
    <listeners>
      <remove name="Default"/>
      <add name="ExceptionListener" type="Namespace.ExceptionTraceListener,AssemblyName"/>
    </listeners>
  </trace>
 </system.diagnostics>

Ich weiß nicht, wie es in C # und .NET ist, aber in C wird behaupten () nur dann, wenn mit -DDEBUG kompiliert arbeiten - die Enduser nie eine assert () sehen, ob es ohne kompiliert. Es ist für Entwickler nur. Ich benutze es wirklich oft, ist es manchmal einfacher Fehler zu verfolgen.

Ich würde sie nicht in Produktionscode verwenden. Werfen Ausnahmen fangen und protokollieren.

Auch müssen vorsichtig in asp.net sein, als eine Assertion auf der Konsole erscheinen kann und frieren die Anfrage (n).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top