Verifica se un metodo restituisce falso: assegna il risultato alla variabile temporanea o metti direttamente l'invocazione del metodo in condizionale?

9

È consigliabile chiamare un metodo che restituisce valori veri o falsi in un'istruzione if?

Qualcosa del genere:

private void VerifyAccount()
{
    if (!ValidateCredentials(txtUser.Text, txtPassword.Text))
    {
        MessageBox.Show("Invalid user name or password");
    }
}

private bool ValidateCredentials(string userName, string password)
{
    string existingPassword = GetUserPassword(userName);
    if (existingPassword == null)
        return false;

    var hasher = new Hasher { SaltSize = 16 };
    bool passwordsMatch = hasher.CompareStringToHash(password, existingPassword);

    return passwordsMatch;
}

o è meglio memorizzarli in una variabile, quindi confrontarli usando if else valori come questo

bool validate = ValidateCredentials(txtUser.Text, txtPassword.Text);
if(validate == false){
    //Do something
}

Non mi sto riferendo solo a .NET, mi riferisco alla domanda in tutti i linguaggi di programmazione, ma così è successo che ho usato .NET come esempio

    
posta KyelJmD 25.02.2012 - 18:35
fonte

7 risposte

26

Come con tutte queste cose, dipende.

Se non si utilizzerà il risultato della chiamata su ValidateCredentials , non è necessario (tranne che per scopi di debug) archiviare il risultato in una variabile locale. Tuttavia, se rende il codice più leggibile (e quindi più gestibile) per far sì che una variabile entri in quella posizione.

Il codice non sarà misurabilmente meno efficiente.

    
risposta data 25.02.2012 - 18:47
fonte
9

Perché usare una variabile aggiuntiva? Preferisco usare il primo approccio, è più leggibile e semplice.

    
risposta data 25.02.2012 - 18:51
fonte
4

Is it a good practice to call a method that returns true or false values in an if statement?

Sì, se il condizionale non è abbastanza semplice da incorporare e deve essere leggibile.

or is it better to store them in a variable then compare them using if else values like this

Dovresti farlo solo se usi il valore in più punti o ne hai bisogno per rendere il codice più leggibile. Altrimenti l'assegnazione a una variabile non è necessaria. Il codice non necessario è nel migliore dei casi uno spreco e nel peggiore una fonte di un difetto.

    
risposta data 25.02.2012 - 19:38
fonte
2

Vediamo ...

Poiché si tratta di KISS , non è necessario creare una variabile aggiuntiva quando puoi farne a meno. Inoltre, non è necessario digitare altro ... quando non ce n'è bisogno.

Ma poi perché DRY , se in seguito chiamavi ValidateCredentials e ti ritrovavi a digitare ValidateCredentials(txtUser.Text, txtPassword.Text) sai che dovresti hai creato una variabile aggiuntiva.

    
risposta data 25.02.2012 - 23:30
fonte
2

Sì, di solito è bene usare metodi come se fossero condizioni. È utile se il nome del metodo indica che il metodo restituisce un valore booleano; ad esempio CanValidateCredentials. Nei linguaggi in stile C questo metodo assume spesso la forma di prefissi Is e Can e in Ruby con '?' suffisso.

    
risposta data 25.02.2012 - 19:07
fonte
1

C'è un'altra preoccupazione che non è stata ancora sottolineata: valutazione del cortocircuito . Qual è la differenza tra questi due frammenti di codice?

Ex # 1:

if(foo() && bar() && baz())
{
    quz();
}

Ex # 2:

bool isFoo = foo();
bool isBar = bar();
bool isBaz = baz();
if(isFoo && isBar && isBaz)
{
    quz();
}

Questi due frammenti di codice sembrano fare la stessa cosa, ma se il tuo linguaggio supporta la valutazione di cortocircuito, questi due frammenti sono diversi. Valutazione del cortocircuito significa che il codice valuterà il minimo necessario per superare o fallire una condizione. Se l'esempio # 1, se foo () restituisce false, bar () e baz () non vengono nemmeno valutati. Questo è utile se baz () è una chiamata di funzione di lunga durata perché puoi saltare se foo () restituisce false o foo () restituisce true e bar () restituisce false.

Questo non è il caso dell'esempio n. 2. foo (), bar () e baz () vengono sempre valutati. Se ti aspetti che bar () e baz () mostrino effetti collaterali, avrai problemi con Example # 1. L'esempio # 1 sopra è in realtà equivalente a questo:

Ex # 3:

if(foo())
{
    if(bar())
    {
        if(baz())
        {
            quz();
        }
    }
}

Sii consapevole di queste differenze nel codice quando scegli tra gli esempi # 1 e # 2.

    
risposta data 07.12.2015 - 21:20
fonte
1

Espansione un po 'del problema di leggibilità ...

Posso pensare a due buoni motivi per archiviare il risultato in una variabile:

  1. Se stai per utilizzare la condizione più di una volta, salvarla in una variabile significa che devi chiamare la funzione una sola volta. (Questo presuppone che il valore memorizzato sia ancora valido, se hai bisogno di ri-testarlo, ovviamente questo non si applica.)

  2. Se memorizzarlo in una variabile migliora la leggibilità dando alla condizione un nome più significativo di quello che vedi nella chiamata alla funzione.

Ad esempio, questo:

bool foo_is_ok = is_ok(foo);
if (foo_is_ok) ...

non aiuta la leggibilità, ma questo:

bool done_processing = feof(file1) && feof(file2);
if (done_processing) ...

probabilmente lo è, dal momento che non è immediatamente evidente che feof(file1) && feof(file2) significa che abbiamo terminato l'elaborazione.

La variabile passwordsMatch nella domanda è probabilmente un esempio migliore della mia.

Le variabili monouso sono utili se danno un nome significativo ad un certo valore. (Questo è ovviamente a beneficio del lettore umano.)

    
risposta data 26.02.2012 - 01:32
fonte