2017-04-20 3 views
0

Ich weiß, dass dieses Problem bereits auf der Website behoben wurde. Allerdings gibt es viele verschiedene Meinungen und ich würde es gerne tiefer verstehen, um zu wissen, wie man bestimmten Situationen gegenübersteht. Sagen wir, ich habe den folgenden Code. Ich werde in C# schreiben, obwohl es keine streng verwandte C# -Frage ist.Wie Validierung ungültigen Arguments behandelt

class Player 
{ 
    private int dexterity; 
    public int Dexterity{ 
     get => dexterity; 
     set{ 
      //Here I need to validate: problem 2 
      dexterity = value; 
      UpdateArmorClass(); //Armor class should be modified any time dex is 
     } 
    private int armorClass; 

    public Player(int dex){ 
     Dexterity = dex; 
    } 

    private void UpdateArmorClass(){ 
     //Should I validate here? Problem 3 
     armorClass = 10 + Dexterity; 
    } 
} 
//Here is main with user input: problem 1 

wir sagen Lassen Sie einen Benutzer zur Eingabe seiner detxterity gefragt wird, die nicht negativ sein muss, seinen Charakter zu erstellen. Jetzt stehe ich vor drei Situationen:

  • Problem 1: Benutzereingabevalidierung: Lesen um, ich habe davon überzeugt, dass ich nie Ausnahmen verwenden shuold Benutzereingaben zu validieren, da es etwas, das sehr häufig auftritt. Ich denke, ich kann dieses Problem lösen, indem ich ein boolesches isValid benutze und den Benutzer erneut auffordere, seinen Wert einzugeben, wenn es falsch ist. Ist das eine gute Lösung?
  • Problem 2: Validierung in einem Konstruktor: gut, es ist nicht wirklich in den Konstruktor, ich habe es in der Setter Geschicklichkeit setzen, die durch den Konstruktor aufgerufen wird. A priori, es gäbe keine Notwendigkeit, dies zu überprüfen, denn wenn die Benutzereingabe bereits validiert wurde, werden die Daten korrekt sein. Obwohl, ich Spieler irgendwo anders im Code erstellen können (so möchte ich auf Programmierer Ebene und nicht auf Benutzerebene überprüfen) und Geschicklichkeit shuold nie negativ sein dürfen. Hier stehe ich vor dem großen Dilemma: Ausnahmen verwenden oder nicht? Ich würde sie verwenden, um zu verhindern, dass das Programm ein ungültiges Objekt generiert. Obwohl, viele entmutigen Ausnahme wegen seiner Teuerheit. Die einzige Lösung, die ich mir vorstellen kann, ist die Vorgabe von Standardwerten, wenn die angegebenen Werte falsch sind. Allerdings scheint es mir eine knifflige Lösung zu sein, da das Programm ungestört weitergeht und ich nicht weiß, dass ein Standardwert eingestellt wurde (was für meine Situation falsch sein kann). Also die eigentliche Frage: sollte ich Ausnahmen verwenden, um solche Situationen in Costruktoren (oder Setter) zu behandeln?
  • Problem 3: Validierung in einer Methode: jetzt weiß ich auch, dass armorClass niemals negativ sein darf. In meiner Situation habe ich eine private Methode, die Rüstungsklasse jederzeit aktualisiert, wenn die Geschicklichkeit geändert wird. So gibt es wirklich keine Notwendigkeit hier wieder zu validieren. Nun nehme ich an, ich mache eine andere Klasse, die benutzt wird, um einen einfachen Kampf zu machen, und ich habe am Ende dieses Beitrags die Methode angezeigt, die die Trefferwahrscheinlichkeit berechnet. Es erwartet einen gewissen armorClass-Wert, obwohl ich ein anderer Programmierer bin und nicht wissen kann, ob die armorClass im Player bereits validiert wurde. Also überprüfe ich, ob es nicht negativ ist. Eine Ausnahme für eine solche Überprüfung zu werfen scheint zu viel, obwohl, wenn ich seine Nicht-Negativität überprüfe, ich einen Standardwert zurückgeben muss, wenn die armorClass negativ ist, was schwierig scheint. Was soll ich in dieser Situation tun?

Hier ist die letzte Methode:

public float Hit(int armorClass){ 
    if(armorClass >=0) //calculate probability of being hit 
    //return probability 
} 

Bonus Frage (bezogen auf die vorangegangenen Fragen natürlich): ist das wirklich teuer eine neue Ausnahme instanziieren? Oder ist es nur der Versuch, zu fangen? Für mich scheint es, als würde man ein neues Objekt instantiieren und das ist alles. Obwohl ich falsch liegen könnte, sagen viele, dass Sie keine Ausnahmen verwenden sollten, wenn sie nicht wirklich gebraucht werden.

+0

nicht im Zusammenhang mit Ihrer Frage: in Setter, 'Geschicklichkeit = Geschicklichkeit;' sollte 'Geschicklichkeit = Geschicklichkeit sein;' –

+0

Ja, eigentlich war das ein Tippfehler. Ich benutze 'Geschicklichkeit = Wert 'in C#, aber ich nehme an, dass Ergebnisse in der gleichen Sache wie Sie geschrieben haben. – Harnak

+0

sicher, 'Geschicklichkeit = Wert ': mein Tippfehler auch! –

Antwort

2

Hier stehe ich vor dem großen Dilemma: Ausnahmen verwenden oder nicht? Ich würde persönlich verwenden, um zu verhindern, dass das Programm ein ungültiges Objekt erzeugt. Allerdings, viele entmutigen Ausnahme Verwendung aufgrund seiner hohen Kosten.

Verwenden Sie die Ausnahme. Ausnahmen sind nur dann teuer, wenn sie ausgelöst werden, und es ist immer besser, eine Ausnahme auszulösen, als mit beschädigten Objekten zu enden. Wenn Ihre Werte von Benutzereingaben stammen, behandeln Sie ungültige Werte, bei denen Sie sie vom Benutzer erhalten, separat. Auf diese Weise können Sie diese Methoden/Set-Werte sicher aus dem Code aufrufen, und Sie erhalten keine Exceptions, wenn der Benutzer ungültige Werte eingibt. Außerdem gibt es manchmal spezielle Werte, die Sie verwenden dürfen, die der Benutzer nicht eingeben darf.

Problem 3: Wenn Ihr privates Feld immer vor dem Festlegen überprüft wird, hat es keinen Sinn zu überprüfen, ob es gültig ist. In Ihrem Codebeispiel wird das Hinzufügen von 10 zu einer nicht negativen Zahl immer einen nicht negativen Wert ergeben.

Bonus Frage: Alle erhabenen Ausnahmen müssen irgendwo behandelt werden, also denke ich nicht, es ist egal, ob es der Raising-Teil ist, der teuer ist, oder der Fangteil.

+0

Vielen Dank für Ihre klare Antwort! Was ist mit dem letzten Beispiel (mit der öffentlichen Methode in einer anderen Klasse)? Würdest du die Rüstungsklasse dort überprüfen? Wenn die Rüstungsklasse positiv ist: Wahrscheinlichkeit berechnen; sonst, tue nichts/gebe den Standardwert (z. B. 0) zurück. Es fällt mir immer schwer, mir die Konsequenzen dieser Art von Validierung vorzustellen. Allerdings scheint es die einzige Lösung in dieser Situation zu sein. – Harnak

+0

Nun, es ist eine öffentliche Methode, daher ist es möglicherweise nicht die beste Idee, davon auszugehen, dass Ihre Parameter immer gültig sind. Wenn es darum geht, was genau zu tun ist, kommt es auf die Logik an. Wenn deine "armorClass" in einigen Fällen nagativ sein könnte (wie zB ein gegnerischer Modifikator, der alle deine Rüstung wie 1 Stufe niedriger behandelt) und 0 zurückgibt, ist der erwartete Wert für diese Methode, die Rückgabe ist völlig in Ordnung. Wenn "armourClass" niemals negativ sein sollte, ist das Auslösen einer Ausnahme oder die Verwendung von 'Debug.Assert' in Ordnung. Sie können die neueste App verwenden, um Ihre App nicht in der Produktion zum Absturz zu bringen, aber Sie sehen deutlich, dass etwas nicht in Ordnung ist. –

+0

Vielen Dank für Ihren Rat. Das war sehr hilfreich :-) – Harnak

Verwandte Themen