C# Nullable Types: 2 errori nel disegno


Il punto centrale del pattern nullable object o special case che dir si voglia è quello di evitare gli IF per gestire il Null. E invece ...
Nella conversione da int? a string:  non c'è modo di specificare che stringa usare in caso di null senza usare un IF nemmeno con l'operatore ??.  Per es. in una label vorrei poter visualizzare il numero oppure N.A. quando c'è il null e mi tocca mettere un if.    



L'abilita principale di un programmatore è sapersela cavare col codice. E invece...
Al posto di contare sulla capacità dei programmatori di capire e usare correttamente la logica booleana dei NULL standardizzata da SQL ne hanno inventata una nuova perché  "più intuitiva"




Per quanto ogni disegno è opinabile, lo svantaggio qui è evidente
:( nel primo caso un IF in più riduce la semplicità del codice, raddoppia lo sforzo necessario per testarlo e la possibilità di introdurre un bug
:( nel secondo caso un programmatore può dover scrivere un WHERE con una logica SQL dei NULL e un momento dopo una espressione bool? con una logica C# E non voglio sapere quale logica i SqlType  adottano con i NULLABLE BOOL o cosa accade con una espressione bool? in una Stored Procedure C# di SqlServer



A chi fa una osservazione la resposabilità di proporre una alternativa!  Nel primo caso un overload del ToString() che accetta come parametro la stringa per il caso NULL o una implementazione del IFormatter che consente di indicarlo nella stringa di formattazione Nel secondo caso degli extension methods .And .Or .Not che implementano la logica SQL
 
Tags :  |  |

Print | posted @ martedì 24 marzo 2009 20.36

Comments on this entry:

Gravatar # re: C# Nullable Types: 2 errori nel disegno
by raffaeu at 25/03/2009 15.07

Ma a mio parere la seconda opzione non va bene perche' ti lega ad una tecnologia. Non puoi legare la logica di business a come venga gestito il datatype da SQL. Se cambi Db? Se la logica dei null in SQL cambia?
No io direi che la scrittura di custom type o la sovrascrittura di metodi quali Equals() GetHashCode() ToString() e magari una custom collections per queste tipologie di entities e' la soluzione ottimale, che poi ti andrai a riciclare nel tempo. Io <customizzo> il datatype, mi sovrascrivo Equals() GetHashCode() e ToString() e non ho mai avuto problemi se non di gestione del tutto. Ma esiste anche l' ereditarieta' e i generics.
  
Gravatar # re: C# Nullable Types: 2 errori nel disegno
by Raffaele Rialdi at 25/03/2009 19.45

Ciao Luca,
premetto che a me non piace usare i nullable types perché ritengo che portarsi a spasso un null è una perdita di tempo per i controlli che devi introdurre e perché in un database il significato del null è molto diverso da quello usato nei linguaggi.
Tra l'altro mi piace molto spec# proprio per la possibilità di avere i non-nullable types che vorrei vedere in C#. La speranza potrebbe anche non andare vana visto che i code contracts di C# 4.0 sono stati attinti da spec#.

Detto questo ho sempre ammirato la tua implementazione dei nullable che la ritengo un ottimo esempio di come usare certe caratteristiche del linguaggio sconosciute a molti.

Per quanto riguarda il caso string, non mi pare giusto introdurre un 'caso particolare' per le stringhe. Il dev deve sempre ricordarsi l'overhead di un nullable type e del controllo che è obbligatorio sempre e comunque.

Veniamo ai nullable boolean. Nelle specs di C# (24.3.5) si dice:
<quote>
To ensure that the results produced by the & and | operators for bool? operands are consistent with SQL’s three-valued logic, the following predefined operators are provided:
bool? operator &(bool? x, bool? y);
bool? operator |(bool? x, bool? y);
</quote>
Il comportamento implementato mi sembra coerente e soprattutto studiato proprio per evitare i problemi che hai sollevato.

Credo comunque che il signor bool ne avrebbe da dire sulla 'perversione' di un nullable boolean :)

Ciao
  
Gravatar # re: C# Nullable Types: 2 errori nel disegno
by mymailgateway-ugidotnet@yahoo.it at 25/03/2009 19.54

Ciao Raffa,

grazie della risposta chiara e dettagliata. E grazie per i complimenti :)

Questa volta la critica deriva non dal confronto con la mia implementazione (che mi sono ormai scordato) ma con il coding quotidiano.

Se alla fine devo mettere un if (quando devo mettere su una label un int?) l'ìimplementazione del nullab le pattern è sbagliata nelle fondamenta


Sui bool ammetto che la questione è più opinabile, sinceramente con lo standard fatto da chi ha inventato il NULL mi sembra inutile inventarsene un altro. ma come dicevo , è opinabile :)




  
Gravatar # re: C# Nullable Types: 2 errori nel disegno
by fremsoft at 26/03/2009 11.10

Concordo con Raffaele, penso che l'uso di IF o espressioni condizionali (cond?severo:sefalso) sia uno sforzo che il programmatore deve fare.

Se posso fare una proposta, direi di inventare una interfaccia INullableObject che si occupi della gestione dei casi particolari su oggetti `nullabili` come la definizione della stringa da mostrare nel caso di oggetto non definito o tri-state.

Lascierei stare i parametri standard di ToString, ma suggerirei di riscrivere le ToString in modo che tengano conto di parametri definiti in INullableObject che specificherebbero l'output da mostrare in caso di oggetto null.
  
Gravatar # re: C# Nullable Types: 2 errori nel disegno
by Luca Minudel at 26/03/2009 11.42

> penso che l'uso di IF o espressioni condizionali (cond?severo:sefalso) sia uno sforzo che il programmatore deve fare.

il mio pensiero su questo punto e' questo :
nella programmazione moderna l'uso di IF evitabili e' un errore

il pattern nullable object serve proprio a questo

cioe i nullable type del C# hanno fallito il loro scopo principale

  
Gravatar # re: C# Nullable Types: 2 errori nel disegno
by Raffaele Rialdi at 27/03/2009 14.31

Luca, da quello che scrivi cerchi un linguaggio meno imperativo e questo non è C#.

Gli IF inevitabili sono parte integrante della programmazione nei linguaggi imperativi e avrai sempre molti casi in cui sono assolutamente inevitabili.

Prova F# e avrai maggiori soddisfazioni per quel genere di costrutti.
Il vantaggio di F# rispetto ai suoi predecessori funzionali è di poter essere usato *anche* in modo imperativo per quei costrutti che non possono essere espressi diversamente.
  
Gravatar # re: C# Nullable Types: 2 errori nel disegno
by Luca Minudel at 27/03/2009 17.45

> Gli IF inevitabili sono parte integrante della programmazione nei linguaggi imperativi e avrai sempre molti casi in cui sono assolutamente inevitabili.

Per questo caso specifico della conversione da int? a String ne sono emersi almeno 3 possibili modi diversi disponibili col C#

Perché dici che serve F# ?
  
Gravatar # re: C# Nullable Types: 2 errori nel disegno
by Raffaele Rialdi at 27/03/2009 21.23

Sto facendo un discorso generale. Ad ogni modo considerato che il significato del null cambia a seconda del contesto, le assunzioni che fai per evitare l'if possono stravolgere il significato del null in quel contesto. Sul db il null può stare per diverse cose: 'non applicabile', 'entità non esistente' (outer join), 'default', etc.

Ma dicevo che il mio è un discorso più generale. I linguaggi imperativi come C#, C++, VB devono esprimere l'algoritmo 'guidando' il flusso dell'algoritmo.
Certo alcune volte puoi cercare di semplificare usando OOP ma se l'algoritmo è complesso l'IF è inevitabile per la natura stessa del linguaggio.

I linguaggi funzionali partono da un concetto differente e descrivono una pipeline di costrutti che puoi montare a piacere. Gli IF sono praticamente inesistenti in tutte le dichiarazioni funzionali pure.
Ma visto che prima o poi ti trovi ad usare delle funzioni di libreria o a dover comunque esprimere qualcosa in modo imperativo, F# salva capra e cavoli e ti permette anche di scrivere codice imperativo.
  
Gravatar # re: C# Nullable Types: 2 errori nel disegno
by Luca Minudel at 28/03/2009 0.05

siamo tutti e 2 pignoli ma quando l'argomento permette di spiegrarci spesso scopriamp di essere d'accordo :)

> il significato del null cambia a seconda del contesto

si è proprio come dici, in parti diverse del codice mi capita di convertire il null in cose diverse (es. 0 in una somma o 1 in una moltiplicazione) e cosi evito l'if

> Ma dicevo che il mio è un discorso più generale.

adesso ho capito e concordo. ho notato che anche in C# togliendo gli if evitabili e duplicati si possono ridurre anche del 60-90% e mi pare un bel risultato - anche i linguaggi dichiarativi mi piacciono quindi aspetto con curiosità e interesse C# 4.0 con unpo di #Spec e IronRuby con il paradigma funzionale :)
  

Your comment:

Title:
Name:
Email:
Website:
 
Italic Underline Blockquote Hyperlink
 
 
Please add 8 and 6 and type the answer here: