PDA

View Full Version : [C#]Ridurre gli If


RaouL_BennetH
13-10-2008, 10:48
Ciao a tutti :)

Anche io nel mio piccolo cerco di aderire alla campagna anti-if :D

La mia piccola e semplice situazione è questa:

Un form di login, due caselle di testo per username e password e
i due classici bottoni di login e annulla.

Ora, il primo controllo che devo fare quando si clicca sul 'login' è che i due textbox non siano vuoti e quindi, mi piacerebbe trasformare questo:



if(txtUsername.Text.Length != 0 && txtPassword.Text.Length != 0)
{
//blablacode
}



Prima di andare avanti, mi piacerebbe sapere da voi come far funzionare questa semplice cosa senza l'ausilio degli if.

N.B.: La mia domanda non ha scopi di efficienza o altro :)

Grazie mille.

RaouL.

gugoXX
13-10-2008, 11:11
Ciao.
Innanzitutto io spezzerei una lancia pro-if, nel senso che non e' detto che un programma senza if sia sempre migliore o piu' leggibile di uno con qualche if nel posto giusto.
Ma qui in effetti qualcosa si puo' fare.
Ma non tanto perche' l'if sia un diavolo, ma piu' che altro tenendo un occhio sulla usabilita' e la user-experience.

Mi spiego, se l'utente non scrive la user o la passord, nel branch else del tuo if molto probabilmente solleversti un'eccezione, che alla fine scriverebbe a schermo qualcosa tipo "hai premuto ok senza scrivere sia user che passord".

Ma brutto deficiente di un programma, perche' mi hai permesso di cliccare su OK se sapevi gia' che avresti sollevato un eccezione nel caso in cui io non avessi scritto sia user che password?

Ti proporrei quindi di intercettare il keypressed sulla editbox sia dello user che della password, nel cui corpo venga valutata la lunghezza della stringa (finora) immessa. Se entrambe le lunghezze sono diverse da zero, allora abiliti il pulsante OK, che altrimenti resta disabilitato.
In questo modo "potresti" evitare il controllo con l'if, in quanto saresti sicuro che se qualcuno ha premuto OK significa che necessariamente c'e' qualcosa nei 2 campi.
Ma non bisogna partire comuqnue cadere in errore. Per ragioni di copertura e di robustezza occorre mettere comunque un controllo.
Ma al posto dell'IF a questo punto puoi valutare l'uso di un "Assert", che e' un check piu' profondo e bloccante. D'altronde se qualcuno riuscisse a cliccare OK nonostante quanto controllato significherebbe che ci sarebbe un errore piu' grave che non una semplice dimenticanza utente.

tomminno
13-10-2008, 11:28
Ciao.
Innanzitutto io spezzerei una lancia pro-if, nel senso che non e' detto che un programma senza if sia sempre migliore o piu' leggibile di uno con qualche if nel posto giusto.
Ma qui in effetti qualcosa si puo' fare.
Ma non tanto perche' l'if sia un diavolo, ma piu' che altro tenendo un occhio sulla usabilita' e la user-experience.

Mi spiego, se l'utente non scrive la user o la passord, nel branch else del tuo if molto probabilmente solleversti un'eccezione, che alla fine scriverebbe a schermo qualcosa tipo "hai premuto ok senza scrivere sia user che passord".

Ma brutto deficiente di un programma, perche' mi hai permesso di cliccare su OK se sapevi gia' che avresti sollevato un eccezione nel caso in cui io non avessi scritto sia user che password?

Ti proporrei quindi di intercettare il keypressed sulla editbox sia dello user che della password, nel cui corpo venga valutata la lunghezza della stringa (finora) immessa. Se entrambe le lunghezze sono diverse da zero, allora abiliti il pulsante OK, che altrimenti resta disabilitato.
In questo modo "potresti" evitare il controllo con l'if, in quanto saresti sicuro che se qualcuno ha premuto OK significa che necessariamente c'e' qualcosa nei 2 campi.
Ma non bisogna partire comuqnue cadere in errore. Per ragioni di copertura e di robustezza occorre mettere comunque un controllo.
Ma al posto dell'IF a questo punto puoi valutare l'uso di un "Assert", che e' un check piu' profondo e bloccante. D'altronde se qualcuno riuscisse a cliccare OK nonostante quanto controllato significherebbe che ci sarebbe un errore piu' grave che non una semplice dimenticanza utente.

Nel caso di un applicativo web la cosa si fa più complicata, visto che non puoi impedire che qualcuno ti mandi i dati "a mano" e l'Assert è inutilizzabile.
L'unica cosa è applicare un controllo lato server.

Per evitare l'if si può pensare ad un Dictionary qualcosa tipo:

delegate void Validate(string message);
Dictionary<bool,Validate> validator = new Dictionary<bool, Validate>();

validator[false] = delegate (string message) { throw new Exception(message);};
validator[true] = delegate(string message) {};

validator[txtUsername.Text.Length == 0]("Username invalido");
validator[txtPassword.Text.Length == 0]("Password non valida");

validator[IsUsernameInDB(txtUsername.Text)]("Username invalido");
validator[IsValidLogin(txtUsername.Text,txtPassword.Text)]("Login non valida");


Il codice perde chiarezza in quanto va letto al contrario.
In caso di applicativi web magari è buona norma non dare indicazioni su cosa è effettivamente sbagliato meglio un generico "Login non valida".

gugoXX
13-10-2008, 11:30
Nel caso di un applicativo web la cosa si fa più complicata, visto che non puoi impedire che qualcuno ti mandi i dati "a mano" e l'Assert è inutilizzabile.
L'unica cosa è applicare un controllo lato server.
Non avevo visto che era web. Chiedo scusa.
Comunque con tecnologie come AJAX.net si potrebbe fare, anche se non lo farei per questioni di performance.

Il codice perde chiarezza in quanto va letto al contrario.
In caso di applicativi web magari è buona norma non dare indicazioni su cosa è effettivamente sbagliato meglio un generico "Login non valida".

Concordo.

tomminno
13-10-2008, 11:43
Non avevo visto che era web. Chiedo scusa.


Non l'ha scritto però è una eventualità da considerare.


Comunque con tecnologie come AJAX.net si potrebbe fare, anche se non lo farei per questioni di performance.


Si lo puoi fare (secondo me sarebbe una inutile complicazione), ma non puoi comunque evitare che ti vengano inviati i dati da un bot.

RaouL_BennetH
13-10-2008, 11:55
L'applicazione non è web.

Già impazzisco con le 'bazzecole' lato client... figuramoci :D

@gugoXX:

Mi faresti un esempio con Assert ?

Grazie mille :)

RaouL.

tomminno
13-10-2008, 12:00
L'applicazione non è web.

Già impazzisco con le 'bazzecole' lato client... figuramoci :D

@gugoXX:

Mi faresti un esempio con Assert ?

Grazie mille :)

RaouL.

Ma gli Assert non servivano solo per il Debug?
Se compili in modalità Release spariscono.

RaouL_BennetH
13-10-2008, 12:07
Eh non lo so :(

Generalmente uso un ErrorProvider per evitare valanghe di messagebox.

ma non vedo come evitare degli if.

71104
13-10-2008, 19:48
Ciao a tutti :)

Anche io nel mio piccolo cerco di aderire alla campagna anti-if :D

La mia piccola e semplice situazione è questa:

Un form di login, due caselle di testo per username e password e
i due classici bottoni di login e annulla.

Ora, il primo controllo che devo fare quando si clicca sul 'login' è che i due textbox non siano vuoti e quindi, mi piacerebbe trasformare questo:



if(txtUsername.Text.Length != 0 && txtPassword.Text.Length != 0)
{
//blablacode
}



Prima di andare avanti, mi piacerebbe sapere da voi come far funzionare questa semplice cosa senza l'ausilio degli if.

N.B.: La mia domanda non ha scopi di efficienza o altro :)

Grazie mille.

RaouL.

usi Windows Forms? Validation Events. in risposta all'evento validating scrivi una cosa del genere:

e.Cancel = (txtUsername.Text.Length == 0);

RaouL_BennetH
14-10-2008, 08:08
usi Windows Forms? Validation Events. in risposta all'evento validating scrivi una cosa del genere:

e.Cancel = (txtUsername.Text.Length == 0);


Si, uso windows forms :)

grazie mille :)

RaouL.

RaouL_BennetH
14-10-2008, 08:28
In effetti... sul validating funziona tutto correttamente.

La domanda che però mi sorge spontanea è:

In un form dove ci sono diverse decine di caselle di testo, è corretto utilizzare questo evento per ogni singola casella?

Grazie mille :)

RaouL.