Frage

Lassen Sie uns sagen ich eine Funktion haben, die einige Integer-Wert zurückgeben muss. aber es kann auch fehlschlagen, und ich muss wissen, wenn es funktioniert.

Welches ist der bessere Weg ist?

public int? DoSomethingWonderful()

oder

public bool DoSomethingWonderful(out int parameter)

Das ist wohl eher eine Art Frage, aber ich bin immer noch neugierig, welche Option Menschen nehmen würden.

Edit: (... Nennen wir es eine Wolke nicht, eine Blackbox nein, warten Wolke ja.) Klärung dieser Code spricht mit einem schwarzen Kasten. I dont care Warum es ist fehlgeschlagen. Ich möchte nur wissen müssen, wenn ich einen gültigen Wert haben oder nicht.

War es hilfreich?

Lösung

Ich mag die Nullable-Version besser, weil Sie die null coalesce Operator verwenden kann ?? drauf steht, z.

int reallyTerrible = 0;
var mightBeWonderful = DoSomethingWonderful() ?? reallyTerrible;

Andere Tipps

Es hängt davon ab, wie Sie der Telefonvorwahl denken soll wie folgt aussehen. Und deshalb, was Ihre Funktion wird verwendet für.

Im Allgemeinen sollten Sie Argumente vermeiden werden. Auf der anderen Seite könnte es schön sein Code wie diese zu haben:

int parameter;
if (DoSomething(out paramameter))
{
  // use parameter
}

Wenn Sie eine Nullable-int haben, wäre es wie folgt aussehen:

int? result = DoSomething();
if (result != null)
{
  // use result
}

Dies ist etwas besser, weil Sie kein Argument aus, aber der Code, wenn die Funktion entscheidet succeeded sieht nicht sehr offensichtlich.

Vergessen Sie nicht, dass es eine weitere Option: Verwenden Sie Exeptions. Tun Sie dies nur, wenn der Fall, wenn Ihre Funktion fehlschlägt ist wirklich ein außergewöhnliches und Art eines fehler Fall.

try
{
  // normal case
  int result = DoSomething()
}
catch (SomethingFailedException ex)
{
  // exceptional case
}

Ein Vorteil der Ausnahme ist, dass man es nicht einfach ignorieren kann. Der Normalfall ist auch einfach zu umsetzbar. Wenn der Ausnahmefall etwas, das man ignorieren könnte, sollten Sie keine Ausnahmen verwenden.

Edit: vergessen zu erwähnen: Ein weiterer Vorteil bietet, eine Ausnahme ist, dass Sie auch Informationen zur Verfügung stellen können Warum der Vorgang fehlgeschlagen ist. Diese Informationen werden von dem Ausnahmetyp vorgesehen ist, Eigenschaften der Exception und der Nachrichtentextes.

Warum nicht eine Ausnahme werfen?

würde ich das Muster in einem Ort in der Net-Bibliothek verwendet, folgt wie:

bool int.TryParse(string s, out value)
bool Dictionary.TryGetValue(T1 key, out T2 value)

Also ich würde sagen:

public bool TryDoSomethingWonderful(out int parameter)

Es hängt wirklich davon ab, was Sie tun.

Ist null eine sinnvolle Antwort? Wenn nicht, würde ich einen bool TryDoSomethingWonderful(out int) Methodenaufruf bevorzugen. Das passt sich mit dem Framework.

Wenn jedoch null ein sinnvoller Rückgabewert ist, int Rückkehr? Sinn macht.

Es sei denn, die Leistung der Hauptanliegen ist, sollten Sie eine int zurückkehren und eine Ausnahme bei einem Fehler werfen.

Ich würde die zweite verwenden, weil ich wahrscheinlich sofort wissen müssen, wenn der Aufruf erfolgreich war, und in diesem Fall würde ich lieber schreiben

int x;
if( DoSomethingWonderful( out x ) )
{
    SomethingElse(x);
}

als

int? x = DoSomethingWonderful();
if( x.HasValue )
{
   SomethingElse(x.Value);
}

Ich bin für einen Ausgabeparameter verwendet wird. Meiner Meinung nach ist dies die Art von Situation, für die Verwendung eines Ausgangsparameters am besten geeignet ist.

Ja, können Sie den coalesce Operator Code als Einzeiler zu halten, wenn und nur wenn Sie einen anderen Wert haben, dass Sie in dem Rest des Codes verwenden können. Oft finde ich das nicht der Fall ist für mich, und ich würde es vorziehen, einen anderen Codepfad auszuführen, als ich würde, wenn ich erfolgreich in der Lage war, einen Wert abgerufen werden.

        int value;
        if(DoSomethingWonderful(out value))
        {
            // continue on your merry way
        }
        else
        {
            // oops
            Log("Unable to do something wonderful");

            if (DoSomethingTerrible(out value))
            {
                // continue on your not-so-merry way
            }
            else
            {
                GiveUp();
            }
        }

Darüber hinaus, wenn der Wert, den ich wirklich nullable abrufen möge, dann eine Funktion mit einem Ausgabeparameter verwenden und einem boolean Rückgabewert ist, meiner Meinung nach, ist der einfachste Weg, um den Unterschied zwischen „zu sagen, ich war nicht erfolgreich in der Beschaffung von der Wert“und‚der Wert I ist null‘abgerufen werden. Manchmal sorge ich mich über diese Auszeichnung, wie im folgenden Beispiel:

    private int? _Value;
    private bool _ValueCanBeUsed = false;

    public int? Value
    {
        get { return this._Value; }
        set
        {
            this._Value = value;
            this._ValueCanBeUsed = true;
        }
    }

    public bool DoSomethingTerrible(out int? value)
    {
        if (this._ValueCanBeUsed)
        {
            value = this._Value;
            // prevent others from using this value until it has been set again
            this._ValueCanBeUsed = false;
            return true;
        }
        else
        {
            value = null;
            return false;
        }
    }

Meiner Meinung nach ist der einzige Grund, warum die meisten Menschen neigen dazu, keine Ausgabeparameter zu verwenden, weil sie die Syntax umständlich finden. Allerdings fühle ich mich wirklich, dass Ausgabeparameter verwenden, ist die geeignetere Lösung für dieses Problem, und ich fand, dass, wenn ich mich daran gewöhnt habe ich die Syntax viel besser fand einen Nullwert zurück.

Wenn es nur eine Möglichkeit gibt, kann es fehlschlagen, oder wenn Sie nie wissen müssen, Warum es versäumt, ich würde sagen, es ist wahrscheinlich einfacher und leichter mit dem Nullable-Rückgabewert zu gehen.

Im Gegensatz dazu, wenn es mehrere Möglichkeiten gibt, könnte es fehlschlagen, und der Angerufene Code wünschen kann, genau wissen, warum es fehlgeschlagen ist, dann mit dem Out-Parameter gehen und einen Fehlercode anstelle eines bool zurückgeben (alternativ können Sie eine Ausnahme auslösen sondern auf der Grundlage Ihrer Frage, es scheint, dass Sie bereits entschieden haben, nicht eine Ausnahme zu werfen).

Sie sollten dann eher einen Versuch fangen verwenden. Dies scheint, wie der Anrufer nicht weiß, was passieren könnte?

Sollte überprüfen wir beide Bool und aus, oder sollte ich prüfen beide Renditen null und die tatsächlichen Erträge.

Lassen Sie das Verfahren tun, was es soll, und in dem Fall, in dem es ausgefallen ist, lassen Sie die Anrufer wissen, dass es nicht, und der Anrufer hanlde als requied.

Interessanterweise ist meine persönliche Meinung schwankt von der Art des Verfahrens deutlich basiert. Insbesondere dann, wenn der Zweck ist die Methode abrufen einen einzelnen Wert , wie gegenüber „etwas zu tun“.

Beispiel:

bool GetSerialNumber(out string serialNumber)

vs

string GetSerialNumber() // returns null on failure

Der zweite fühlt sich mehr „natürlich“ mich irgendwie, und ebenso:

bool GetDeviceId(out int id)

vs

int? GetDeviceId() // returns null on failure`

Aber ich gebe zu, das wirklich fällt in "Coding-Style" Gebiet.

Oh, und ich würde auch dazu neigen Ausnahme werfen zu begünstigen:

int GetDeviceId() // throws an exception on read failure

Ich bin immer noch nicht verkauft, warum sie so falsch sein würde. Können wir einen Thread auf, dass Oren? ; -)

Ich mag nicht Microsofts „Try“ Muster, in dem die „out“ Parameter verwendet wird, einen Datenpunkt zurückzukehren. Unter anderem in dieser Art und Weise codiert Methoden können nicht in covariant Schnittstellen verwendet werden. Ich würde lieber sehen, ein Verfahren codiert als: T GetValue(out bool Successful) oder vielleicht T GetValue(out GetValueErrorEnum result); oder T GetValue(out GetValueErrorInfo result);, wenn etwas über eine wahr / falsch ist erforderlich. Da jeder Datentyp einen Rechtsstandardwert hat, gibt es kein Problem mit der Entscheidung, was zurück, wenn die Funktion fehlschlägt. Telefonvorwahl kann einfach sagen:

  bool success;
  var myValue = Thing.GetValue(ref success);
  if (success)
    .. do something using myValue
  else
    .. ignore myValue

Es wäre schön, wenn .net und C # true covariant angebotenen Parameter ‚abschreiben‘ (der Anrufer würde Platz für das Ergebnis zuzuweisen, einen Zeiger auf diesen Raum an die aufgerufene Funktion übergeben und dann den zugewiesenen Speicherplatz auf dem übergebenen kopieren -in Variable erst, nachdem die Funktion zurück).

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