|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
[C#]Liberatemi dagli if !
Eccomi
![]() Spero di riuscire a dare una descrizione precisa del problema: Ho una griglia, sulla quale devo valutare alcuni dati inseriti dall'utente. Di volta in volta devo accertarmi che se una determinata cella non ha un dato al suo interno, il programma deve fare determinate cose: questo è il mio horror code: Codice:
private void btnSave_Click(object Sender, EventArgs e) { try { DataBaseManager dbm = new DataBaseManager(); dbm.OpenConnection(); InitializeParameter(); for(int count = 0; count < grid.Rows.Count; count++) { if(grid.Rows[i].Cells[2].Value != null) { //blablabla } else if (grid.Rows[i].Cells[3].Value != null) { //blablabla } else if (grid.Rows[i].Cells[5].Value != null) //blablabla } } catch(MySqlException ex) { blablabl } } ![]() Grazie per l'aiuto. RaouL.
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek ![]() |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quanti if hai ? Solo 3 o ne hai altri ?
|
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
Sono 6, senza considerare che poi dovrei anche immaginare a delle combinazioni del tipo:
se cella[1] e cella[2] sono vuote; oppure se cella[5] oppure cella[7] non sono vuote.... ma se continuo così avrò una catena di if else pari alle righe di codice di un sistema operativo ![]()
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek ![]() |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Allora fai un vettore di vettori.
Ogni vettore dovrà contenere la lista delle celle che devono essere != null per il verificarsi della condizione. Dovresti aggiungere per ogni riga anche un method object (tutti derivati da uno base) che deve essere richiamato al momento in cui tutte le condizioni sono verificate. A questo punto ti scorri tutte le condizioni e le verifichi. La complessità di tempo è sicuramente maggiore, ma ti eviti tutti gli if. Se le condizioni dovessero diventare più complicate dovresti organizzare il tutto in un albero binario in modo da non dover verificare tante volte le stesse condizioni le condizioni. |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
Uhm
![]() ![]()
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek ![]() |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12093
|
per me basterebbe scorrerti anche le colonne oltre le righe e riduci tutto a qualcosa del genere:
Codice:
for(int i = 0; i < grid.Rows.Count; i++) { for(int j = 0; j < grid.Rows.Cells.Count; j++) { getClass().getMethod("cellNotNull" + j).invoke(); } } ![]() P.S. e cmq non è per nulla complicato dato che per usare la reflection dubito che tu debba scrivere + di 5 righe di codice ![]()
__________________
![]() |
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
Credo allora di dovermi leggere qualcosa sulla reflection, dato che sinceramente non so cosa sia
![]()
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek ![]() |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3691
|
Lascia perdere.
Se le varie blablabla sono tutte diverse l'una dall'altra, a seconda della colonna che stai processando, usare i 2 for annidati con la reflection non fa che spostare il problema. Il codice dei vari blablabla lo dovrai scrivere comunque, da un'altra parte, e forse renderendo il tutto meno leggibile. farei cosi' Codice:
for(int i = 0; i < grid.Rows.Count; i++) { for(int j = 0; j < grid.Rows.Cells.Count; j++) { if (grid[i][j]!=null) { switch(j) { case 1:blablabl break; case 2: balbalbalb break; case n: blbalblablablab break; } } } } Se invece i vari blablabla fossero tutti uguali o molto simili tra loro, allora se ne puo' discutere ed ottimizzare.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 08-02-2008 alle 21:22. |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12093
|
Quote:
Ma può benissimo crearsi una classe ValidationHandler (o quello che è a seconda di quello che deve fare) e, volendo, anche utilizzare dei metodi dal nome significativo (tipo validateNameNull e cose del genere) semplicemente inserendo in una mappa l'intero corrispondente alla posizione corrente della colonna con il nome del metodo. Per me è MOOOLTO + leggibile di uno switch case che trovo orribile al pari degli if ![]()
__________________
![]() |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3691
|
Ma tanto non funzionerebbe.
Se i contenuti di 2 celle sono dello stesso tipo, i cui 2 blablabla da farsi sono pero' diversi, durante l'invocazione del metodo in reflection come li distingui? (PS con il C#3.0 ci sono i metodi extension, quindi sarebbe anche possibile e piu' elegante della reflection)
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3691
|
Ho capito cosa vuoi dire.
L'if lo faresti fare alla reflection. Si puo' fare anche senza reflection, facendo fare l'if al polimorfismo, ma per me resta meno leggibile. E soprattutto meno leggibile anche per il mio vicino di scrivania, che magari fra un anno e mezzo deve cambiare qualcosa.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12093
|
Quote:
in base alla posizione. Immagina questa situazione: Codice:
cella1 cella2 cella3 cella4 code1 code2 code3 code4 Ora immagine uno string array così fatto: Codice:
string[] handlerMethodsNames = new string[] {"handleThis", "handleThat", "handleAnother", handleAnotherOne"}; Codice:
for(int i = 0; i < grid.Rows.Count; i++) { for(int j = 0; j < grid.Rows.Cells.Count; j++) { getClass().getMethod(handlerMethodsNames[j]).invoke(); } } In questo modo hai concentrato nella classe handler tutti i metodi da invocare per la validazione (o quello che è) delle celle e, se hai usato un nome significativo, sai esattamente quale metodo andare a cercare nel caso tu debba modificare il codice di qualche cella. Ma soprattutto, cosa non banale, hai ridotto di n volte la complessità ciclomatica del metodo originale della tua classe e aumentato conseguentemente la leggibilità del tutto ![]()
__________________
![]() |
|
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3691
|
Si', esatto come pensavo volessi fare.
Sparpagli il codice in giro, in funzioni che vengono chiamate da un punto solo del programma. Comunque basta un array di delegate per fare quello che proponi.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 08-02-2008 alle 21:55. |
![]() |
![]() |
![]() |
#14 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12093
|
Quote:
i delegate li ho usati solo negli handlers dei listener per ora... Ancora non so una mazza di C# ![]() dovessi mai trovare un attimo di tempo dovrei leggermi giusto un paio di libri al riguardo ![]()
__________________
![]() |
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3691
|
Te li consiglio, risolvono tantissimi problemi e talvolta non se ne puo' fare a meno (come nei thread)
Ho inziato a studiare una nuova forma di delegate del C#3.0, le lambda function. Su alcuni esempi che ho visto sono davvero concise e potenti.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12093
|
Quote:
![]() Ora mi sa che me ne servirebbe qualcuno in particolare sul linguaggio perchè ho notato che, nonostante le similitudini con java, per alcune cose che in java mi verrebbero immediate ci perdo troppo tempo in C#....
__________________
![]() |
|
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3691
|
Quelli rossi con copertina in sfondo nero, della Microsoft Press sono fatti abbastanza bene.
E soprattutto la gente che li scrive e' davvero disponibile. Mi e' capitato piu' volte di mandare mail chiedendo spiegazioni e si sono dimostrati piu' volte tutti molto disponibili. Quelli che hanno scritto il manuale della LINQ extension sono italiani!
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3691
|
Eccolo, con i delegate.
Ma continuo a pensare che in azienda avrebbero preferito lo switch. Codice:
class Program { delegate int ProcessaColonna(object val); static int PRCol1(object val) { //BLABLABLA return 0; } static int PRCol2(object val) { //BLABLABLA return 0; } static int PRCol3(object val) { //BLABLABLA return 0; } static int[][] cella = null; //solo per compilare. static void Main(string[] args) { List<ProcessaColonna> fnarr=new List<ProcessaColonna>(); fnarr.Add(PRCol1); fnarr.Add(PRCol2); fnarr.Add(PRCol3); for (int t = 0; t < 10; t++) { for (int u = 0; u < 10; u++) { object obj=cella[t][u]; if (obj!=null) fnarr[u].Invoke(obj); } } } }
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 08-02-2008 alle 22:26. Motivo: mancava l'if, la cosa piu' importante |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:24.