2013-07-21 16 views
8

Io lavoro in C#, quindi ho postato questo sotto C# anche se questa potrebbe essere una domanda a cui è possibile rispondere in qualsiasi linguaggio di programmazione.Metodi che restituiscono valori di ritorno significativi

A volte creerò un metodo che eseguirà qualcosa come registrare un utente in un sito Web. Spesso restituisco un booleano dal metodo, ma questo spesso causa problemi perché un valore di ritorno booleano non trasmette alcun contesto. Se si verifica un errore durante la registrazione dell'utente, non ho modo di sapere cosa ha causato l'errore.

Ecco un esempio di un metodo che attualmente utilizzo, ma vorrebbe cambiare in modo che restituisca più di 0 o 1.

public bool LoginToTwitter(String username, String password) 
{ 
    // Some code to log the user in 
} 

Il metodo di cui sopra non può che restituire true o false. Questo funziona bene perché posso solo chiamare il seguente:.

if(http.LoginToTwitter(username, password)) 
{ 
    // Logged in 
} else { 
    // Not Logged in 
} 

Ma il problema è che non ho modo di sapere il motivo per cui l'utente non è stato registrato in una serie di motivi potrebbe esistere come ad esempio: sbagliato username/password combinazione, account sospeso, account richiede l'attenzione degli utenti ecc. Ma usando il seguente metodo e la logica, non è possibile saperlo.

Quali approcci alternativi ho?

risposta

8

È possibile creare e restituire un enum con LoginResults previsti.

public enum LoginResult 
{ 
    Success, 
    AccountSuspended, 
    WrongUsername, 
    WrongPassword, 
} 

Poi ritorno utilizzando il tipo enum nel metodo:

public LoginResult LoginToTwitter(String username, String password) 
{ 
    // Some code to log the user in 
} 
+0

Cosa succede quando si verifica una nuova condizione di errore. @ Dan? – xhamr

+0

@jvra Se ci sono eccezioni impreviste, credo che dovrebbero essere ridisegnate come indicano alcune delle altre risposte. Tuttavia, il codice dovrebbe essere in grado di gestire tutti i casi previsti: nome utente errato, password errata, sospensione dell'account, ecc. E restituire i casi previsti nell'enumerazione per l'applicazione da gestire. –

+0

Ma il fatto è che quando si vuole gestire altro errore enum. il tuo codice potrebbe crescere man mano che aumenti le tue costanti enum. ma è accettabile se sai che in futuro non potresti avere più enum di costanti. – xhamr

8

Si potrebbe scegliere di un'eccezione con un messaggio relativo allegato (e hanno il metodo chiamante accordo con l'eccezione), o avere la funzione restituire un enum con stati diversi (come LoginState.Success, LoginState.IncorrectPassword, ecc.).

Se si utilizza eccezioni, probabilmente è meglio avere il vostro nulla funzione di ritorno (public void LoginToTwitter), ma se si sta utilizzando un enum, assicurarsi che il set il tipo di ritorno al nome del vostro enum (public LoginState LoginToTwitter).

6

Esistono due metodi standard. Se sei interessato solo al risultato, ma non a tutti i metadati, restituisci alcuni enum. Impostare i valori disponibili su Success, Suspended, ecc. (Tutti i possibili risultati)

Se sono necessari ulteriori dettagli, è sempre possibile utilizzare le eccezioni. In pratica, segui l'idea "racconta, non chiedere" e scrivi la tua funzione in modo che restituisca i valori richiesti (ad esempio, l'id utente o forse nulla se hai uno stato di accesso globale) solo in caso di successo e genera un'eccezione con dettagli descrizione dell'errore altrimenti. Per quanto riguarda la gerarchia stessa, molto probabilmente dovresti implementare uno LoginException con alcune sottoclassi più specifiche e prenderne solo quelle. (semplifica la verifica di tutte le eccezioni rilevanti gestite e tutte quelle sconosciute passate a livelli superiori)

0

In base alla tendenza del codice pulito, è necessario fornire un nome significativo per il metodo che rivela l'intenzione.

Per sapere cosa è successo se l'operazione di registrazione non può essere completata, è possibile introdurre nel flusso Exceptions e gestirlo nel contesto del chiamante.

vedere http://msdn.microsoft.com/en-us/library/ms173160(v=vs.80).aspx

3

Sia la restituzione di un enum o di un'eccezione, come suggerito in altre risposte, sono ragionevoli. Ma la mia preferenza è restituire un'eccezione. Sembra pazzesco, ma consente al chiamante di decidere se utilizzare il controllo degli errori o la gestione delle eccezioni. E, a differenza dell'enum, le eccezioni sono gerarchiche, quindi rende molto più facile gestire intere categorie di errori e può trasportare dati extra arbitrari.

Penso che Sayse avesse un'idea simile, ma ha cancellato la sua risposta e non l'ha mai nemmeno spiegata.

+0

Quindi in pratica, 'null' significherebbe * successo * - che sembra piuttosto contro-intuitivo. E ovviamente se hai effettivamente bisogno di un valore di ritorno, come (diciamo) l'informazione dell'utente ... Posso vedere un buon caso in un linguaggio come Smalltalk, che è digitato in modo dinamico, ma un linguaggio tipizzato staticamente come C# rende questo ingombrante . – cHao

+0

@cHao: se l'ulteriore elaborazione richiede la restituzione di altre informazioni, il lancio delle eccezioni inizia a essere più sensato. Ma se l'errore di accesso è un risultato previsto ... beh, non uso 'throw' per condizioni non eccezionali. –

+0

Sono quasi sorpreso che nessuno è considerato un tipo "LoginResult" che non è un'eccezione, ma non è solo un enum. Fornirebbe la flessibilità di restituire informazioni arbitrarie, senza tentare di lanciare eccezioni per condizioni non eccezionali. – cHao

0

È possibile utilizzare un linguaggio utilizzato frequentemente in c. Il risultato di un'espressione di assegnazione è l'espressione in sé - questo significa che è possibile catturare un codice risultato allo stesso tempo, come valutare se si tratta di un valore particolare:

if ((status = DoSomething()) == AnErrorEnum.NotAnError) 
{//success handler 
} 
else 
{//failure handler 
} 

mi è stato chiesto di fornire un link ad un articolo di MSDN - qui è una vecchia versione delle specifiche:. http://msdn.microsoft.com/en-us/library/aa691315(v=vs.71).aspx

"il risultato di una semplice espressione di assegnazione è il valore assegnato alla operando a sinistra il risultato ha lo stesso tipo come operando sinistro ed è sempre classificato come un valore. "

+0

Questo è interessante. Qualsiasi collegamento ai documenti MSDN per favore? –

+0

È nella specifica, che è disponibile per il download: ecco la sezione della vecchia specifica del 2003: http://msdn.microsoft.com/en-us/library/aa691315(v=vs.71).aspx –

Problemi correlati