13 Stimmen

Wie kann man angeben, dass eine Methode erfolglos war?

Ich habe mehrere ähnliche Methoden, z.B. CalculatePoint(...) und CalculateListOfPoints(...). Gelegentlich kann es vorkommen, dass sie nicht erfolgreich sind, und dies muss dem Aufrufer angezeigt werden. Für CalculateListOfPoints, das eine generische Liste zurückgibt, könnte ich eine leere Liste zurückgeben und den Aufrufer auffordern, dies zu überprüfen; Point ist jedoch ein Werttyp und daher kann ich dort nicht null zurückgeben.

Im Idealfall möchte ich, dass die Methoden ähnlich "aussehen"; eine Lösung könnte darin bestehen, sie als

public Point CalculatePoint(... out Boolean boSuccess);
public List<Point> CalculateListOfPoints(... out Boolean boSuccess);

oder alternativ einen Punkt? für CalculatePoint zurückgeben, und null zurückgeben, um einen Fehler anzuzeigen. Das würde bedeuten, dass man zurück zum nicht-nullbaren Typ casten muss, was übertrieben erscheint.

Eine andere Möglichkeit wäre, den Boolean boSuccess zurückzugeben, das Ergebnis (Punkt oder Liste) als 'out'-Parameter zu haben und sie TryToCalculatePoint oder so zu nennen...

Was ist die beste Praxis?

Bearbeiten: Ich möchte keine Ausnahmen für die Flusskontrolle verwenden! Ein Fehlschlag wird manchmal erwartet.

1voto

Rob Punkte 44368

Zusammenfassend gibt es mehrere Ansätze, die Sie verfolgen können:

  1. Wenn der Rückgabetyp ein Wert-Typ ist, wie Point, verwenden Sie die Nullable-Funktion von C# und geben einen Point? (auch bekannt als Nullable) zurück, so dass Sie bei einem Fehler immer noch null zurückgeben können.
  2. Eine Ausnahme auslösen, wenn ein Fehler auftritt. Das ganze Argument / Diskussion darüber, was ist und ist nicht "außergewöhnlich" ist ein strittiger Punkt, es ist Ihre API, Sie entscheiden, was außergewöhnliches Verhalten ist.
  3. Übernahme eines Modells, das dem von Microsoft in den Basistypen wie Int32 implementierten ähnelt, Bereitstellung von CalculatePoint und TryCalculatePoint (int32.Parse und int32.TryParse) sowie eines throw und eines return bool.
  4. Geben Sie eine generische Struktur aus Ihren Methoden zurück, die zwei Eigenschaften hat, bool Success und GenericType Value.

Je nach Szenario neige ich dazu, eine Kombination aus der Rückgabe von Null oder dem Auslösen einer Ausnahme zu verwenden, da sie mir am "saubersten" erscheinen und am besten zu der bestehenden Codebasis des Unternehmens passen, für das ich arbeite. Meine persönliche Best Practice sind also die Ansätze 1 und 2.

1voto

bltxd Punkte 8467

Das hängt vor allem vom Verhalten Ihrer Methoden und deren Verwendung ab.

Wenn Fehler häufig und unkritisch sind, sollten Ihre Methoden einen booleschen Wert zurückgeben, der den Erfolg anzeigt, und einen out-Parameter verwenden, um das Ergebnis zu übermitteln. Das Nachschlagen eines Schlüssels in einem Hash, der Versuch, Daten über einen nicht blockierenden Socket zu lesen, wenn keine Daten verfügbar sind - all diese Beispiele fallen in diese Kategorie.

Bei unerwarteten Fehlern geben Sie direkt das Ergebnis zurück und melden Fehler mit Ausnahmen. Das Öffnen einer Datei mit Lesezugriff oder die Verbindung zu einem TCP-Server sind gute Kandidaten.

Und manchmal sind beide Wege sinnvoll...

1voto

artur02 Punkte 4401

Rückkehr Point.Empty . Es ist ein .NET-Design-Pattern, ein spezielles Feld zurückzugeben, wenn Sie prüfen wollen, ob die Strukturerstellung erfolgreich war. Vermeiden Sie aus Parameter, wenn Sie können.

public static readonly Point Empty

1voto

Samuel Jack Punkte 31654

Ein Muster, mit dem ich gerade experimentiere, ist die Rückgabe einer Vielleicht . Sie hat die Semantik der TryParse Muster, sondern eine ähnliche Signatur wie das Null-Return-on-Error-Muster.

Ich bin noch nicht überzeugt von der einen oder anderen Seite, aber ich biete sie Ihnen zum gemeinsamen Nachdenken an. Es hat den Vorteil, dass vor dem Methodenaufruf keine Variable definiert werden muss, um den Out-Parameter am Aufrufort der Methode zu halten. Sie könnte auch mit einer Fehler o Nachrichten Sammlung, um den Grund für den Fehler anzugeben.

Die Klasse Maybe sieht in etwa so aus:

/// <summary>
/// Represents the return value from an operation that might fail
/// </summary>
/// <typeparam name="T"></typeparam>
public struct Maybe<T>
{
    T _value;
    bool _hasValue;

    public Maybe(T value)
    {
        _value = value;
        _hasValue = true;
    }

    public Maybe()
    {
        _hasValue = false;
        _value = default(T);
    }

    public bool Success
    {
        get { return _hasValue; }
    }

    public T Value
    {
        get 
            { // could throw an exception if _hasValue is false
              return _value; 
            }
    }
}

0voto

GEOCHET Punkte 20824

Ich würde sagen, die beste Praxis ist, dass ein Rückgabewert Erfolg bedeutet, und ein Ausnahme bedeutet Misserfolg.

In den von Ihnen angeführten Beispielen sehe ich keinen Grund, warum Sie nicht die folgende Methode verwenden sollten Ausnahmen im Falle einer Störung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X