Domanda

Ho fatto un'enorme revisione del codice e un modello che noto ovunque è questo:

public bool MethodName()
{
    bool returnValue = false;
    if (expression)
    {
        // do something
        returnValue = MethodCall();
    }
    else
    {
        // do something else
        returnValue = Expression;
    }

    return returnValue;
}

Non è così che avrei fatto questo, avrei appena restituito il valore quando sapevo cosa fosse. quale di questi due schemi è più corretto?

Sottolineo che la logica sembra essere sempre strutturata in modo tale che il valore di ritorno sia assegnato in una sola plave e nessun codice sia eseguito dopo che è stato assegnato.

È stato utile?

Soluzione

C'è una lunga discussione su questo argomento qui .

Altri suggerimenti

Molte persone consigliano di avere solo un punto di uscita dai metodi. Lo schema che descrivi sopra segue questa raccomandazione.

L'essenza principale di quella raccomandazione è che se devi ripulire un po 'di memoria o stato prima di tornare dal metodo, è meglio avere quel codice in un solo posto. la presenza di più punti di uscita comporta la duplicazione del codice di pulizia o potenziali problemi dovuti alla mancanza del codice di pulizia in uno o più punti di uscita.

Naturalmente, se il tuo metodo è lungo un paio di righe o non necessita di pulizia, potresti avere più ritorni.

Avrei usato ternario, per ridurre le strutture di controllo ...


return expression ? MethodCall() : Expression;

Sospetto di essere in minoranza, ma mi piace lo stile presentato nell'esempio. È facile aggiungere un'istruzione di registro e impostare un punto di interruzione, IMO. Inoltre, se usato in modo coerente, sembra più facile & Quot; pattern match & Quot; che avere più ritorni.

Non sono sicuro che ci sia un " corretto " rispondere a questo, tuttavia.

Alcuni istituti e libri di apprendimento sostengono la pratica del ritorno singolo.

Se è meglio o meno è soggettivo.

Sembra una parte di un cattivo design OOP. Forse dovrebbe essere sottoposto a refactoring a un livello superiore rispetto a quello all'interno di un singolo metodo.

Altrimenti, preferisco usare un operatore ternario, come questo:

return expression ? MethodCall() : Expression;

È più breve e più leggibile.

Torna immediatamente da un metodo in una di queste situazioni:

  1. Hai trovato una condizione al contorno e devi restituire un valore univoco o sentinella: if (node.next = null) return NO_VALUE_FOUND;
  2. Un valore / stato richiesto è falso, quindi il resto del metodo non si applica (ovvero una clausola di protezione). Ad es .: if (listeners == null) return null;
  3. Lo scopo del metodo è trovare e restituire un valore specifico, ad es. if (nodes[i].value == searchValue) return i;
  4. Sei in una clausola che restituisce un valore univoco dal metodo non utilizzato altrove nel metodo: if (userNameFromDb.equals(SUPER_USER)) return getSuperUserAccount();

Altrimenti, è utile avere solo un'istruzione return in modo che sia più facile aggiungere la registrazione debug, la pulizia delle risorse e seguire la logica. Provo a gestire prima tutti i 4 casi precedenti, se applicabili, quindi dichiarare una variabile denominata result(s) il più tardi possibile e assegnare i valori a quella necessaria.

Entrambi svolgono lo stesso compito. Alcuni sostengono che un metodo dovrebbe avere solo una voce e un punto di uscita.

Uso anche questo. L'idea è che le risorse possono essere liberate nel normale flusso del programma. Se esci da un metodo in 20 luoghi diversi e devi chiamare cleanUp () prima, dovrai aggiungere un altro metodo di pulizia 20 volte (o refactoring tutto)

Immagino che il programmatore abbia preso il progetto di definire un oggetto Restituire all'inizio del metodo (es. Elenco < Foo > toReturn = new ArrayList < Foo gt; ();) e quindi popolarlo durante la chiamata del metodo, e in qualche modo ha deciso di applicarlo a un tipo di ritorno booleano, che è dispari.

Potrebbe anche essere un effetto collaterale di uno standard di codifica che afferma che non puoi tornare nel mezzo di un corpo del metodo, solo alla fine.

Anche se nessun codice viene eseguito dopo l'assegnazione del valore restituito, ciò non significa che non sarà necessario aggiungere un po 'di codice in seguito.

Non è il più piccolo pezzo di codice che potrebbe essere utilizzato, ma è molto adatto al refactoring.

Delphi forza questo modello creando automaticamente una variabile chiamata " Risultato " che sarà del tipo restituito dalla funzione. Qualunque sia & Quot; Risultato & Quot; è quando la funzione esce, è il valore restituito. Quindi non c'è & Quot; return & Quot; parola chiave.

function MethodName : boolean;
begin
  Result := False;
  if Expression then begin
    //do something
    Result := MethodCall;
  end
  else begin
    //do something else
    Result := Expression;
  end;

  //possibly more code
end;

Il modello utilizzato è dettagliato, ma è anche più facile eseguire il debug se si desidera conoscere il valore restituito senza aprire la finestra Registri e controllare EAX.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top