[c#] Quale è meglio, valore di ritorno o parametro di uscita?


7 Answers

Generalmente si dovrebbe preferire un valore di ritorno su un parametro out. I params out sono un male necessario se ti ritrovi a scrivere codice che deve fare 2 cose. Un buon esempio di questo è il pattern Try (come Int32.TryParse).

Consideriamo ciò che il chiamante dei tuoi due metodi dovrebbe fare. Per il primo esempio posso scrivere questo ...

int foo = GetValue();

Si noti che posso dichiarare una variabile e assegnarla tramite il metodo in una riga. Per il 2 ° esempio sembra che questo ...

int foo;
GetValue(out foo);

Ora sono costretto a dichiarare la mia variabile in anticipo ea scrivere il mio codice su due righe.

aggiornare

Un buon posto dove guardare quando si pone questo tipo di domande è il .NET Framework Design Guidelines. Se hai la versione del libro, puoi vedere le annotazioni di Anders Hejlsberg e altri su questo argomento (pagina 184-185) ma la versione online è qui ...

http://msdn.microsoft.com/en-us/library/ms182131(VS.80).aspx

Se ti ritrovi a dover restituire due cose da un'API, allora avvolgerle in una struct / class sarebbe meglio di un out param.

Question

Se vogliamo ottenere un valore da un metodo, possiamo usare entrambi i valori restituiti, in questo modo:

public int GetValue(); 

o:

public void GetValue(out int x);

Non capisco davvero le differenze tra loro e, quindi, non so quale sia il migliore. Puoi spiegarmi questo?

Grazie.




Preferirei la seguente invece di una di quelle in questo semplice esempio.

public int Value
{
    get;
    private set;
}

Ma sono tutti molto simili. Di solito, si dovrebbe usare 'out' solo se hanno bisogno di passare più valori dal metodo. Se vuoi inviare un valore dentro e fuori dal metodo, uno sceglierebbe "ref". Il mio metodo è il migliore, se si restituisce solo un valore, ma se si desidera passare un parametro e ottenere un valore, probabilmente si sceglierà la prima scelta.




Non c'è alcuna differenza reale, i parametri sono in C # per consentire al metodo di restituire più di un valore, questo è tutto.

Tuttavia ci sono alcune lievi differenze, ma non di loro sono davvero importanti:

L'utilizzo del parametro out ti imporrà di utilizzare due righe come:

int n;
GetValue(n);

durante l'utilizzo del valore di ritorno, ti consente di farlo in una riga:

int n = GetValue();

Un'altra differenza (corretta solo per i tipi di valore e solo se C # non inline la funzione) è che l'uso del valore di ritorno necessariamente farà una copia del valore quando la funzione restituisce mentre usa il parametro OUT non lo farà necessariamente.




Penso che uno dei pochi scenari in cui sarebbe utile sarebbe quando si lavora con la memoria non gestita, e si vuole rendere ovvio che il valore "restituito" dovrebbe essere smaltito manualmente, piuttosto che aspettarsi che venga smaltito da solo .




out è più utile quando si tenta di restituire un oggetto dichiarato nel metodo.

Esempio

public BookList Find(string key)
{
   BookList book; //BookList is a model class
   _books.TryGetValue(key, out book) //_books is a concurrent dictionary
                                     //TryGetValue gets an item with matching key and returns it into book.
   return book;
}



Usando la parola chiave out con un tipo di ritorno di bool, a volte è possibile ridurre il bloat del codice e aumentare la leggibilità. (Principalmente quando le informazioni extra nel parametro out vengono spesso ignorate.) Ad esempio:

var result = DoThing();
if (result.Success)
{
    result = DoOtherThing()
    if (result.Success)
    {
        result = DoFinalThing()
        if (result.Success)
        {
            success = true;
        }
    }
}

vs:

var result;
if (DoThing(out result))
{
    if (DoOtherThing(out result))
    {
        if (DoFinalThing(out result))
        {
            success = true;
        }
    }
}



Dovresti quasi sempre usare un valore di ritorno. I parametri ' out ' creano un po 'di attrito per molte API, composizionalità, ecc.

L'eccezione più degna di nota che viene in mente è quando si desidera restituire più valori (.Net Framework non ha tuple fino alla 4.0), come nel TryParse pattern TryParse .




C'è un motivo per usare un parametro out che non è già stato menzionato: il metodo di chiamata è obbligato a riceverlo. Se il tuo metodo produce un valore che il chiamante non deve scartare, facendolo out costringe il chiamante ad accettarlo in modo specifico:

 Method1();  // Return values can be discard quite easily, even accidentally

 int  resultCode;
 Method2(out resultCode);  // Out params are a little harder to ignore

Ovviamente il chiamante può ancora ignorare il valore in un parametro out , ma hai richiamato la loro attenzione su di esso.

Questo è un bisogno raro; più spesso, dovresti usare un'eccezione per un problema reale o restituire un oggetto con informazioni di stato per una "FYI", ma potrebbero esserci circostanze in cui ciò è importante.






Related



Tags

c# c#   reference