C++ vs C# vs stili di codifica
Premessa scontata: sintatticamente ci sono un bel po' si somiglianze fra C/C++ e C#. Non sono uguali. Sono molto simili, però.
Mi ricordo che uno degli errori che commettevo più di frequente, le prime volte in cui mi sono trovato a scrivere C# dopo 3 anni di C++, era questo.
Considerate questo snippet in C/C++:
// C++ Code.
SomeClass* pSomeObject = AllocateAndReturnObject();
if (!pSomeObject) {
// Error Handling Here.
}
Per chi non conosce il C/C++, la faccio breve. In C/C++ viene considerata true qualsiasi espressione diversa da zero. A partire da un intero per arrivare al valore di un puntatore (come nell'esempio sopra - per inciso NULL è un #define per 0).
Da cui l'abitudine di scrivere (provare a scrivere :-))
// C# Code.
SomeType someValue = GetSomeType();
if (someValue) { // This does not compile, since someValue is not of type Boolean.
// Should be: if (someValue != null) {}
}
Fatto 1, 2, 3 ... alla 4a volta uno si adegua.
Se volete, in C++ scrivere:
- if (pointer)
- if (pointer != NULL)
- if (pointer != 0)
è di fatto la stessa cosa.
Poichè non ci sono vincoli di sintassi, può entrare in gioco qualche considerazione stilistica.
A meno che ...
Prendete questo esempio (C++):
SomeData* pData = GetValidData();
if (pData = NULL) {
// Handle errors.
}
pData->Value = 42;
Sapete trovare l'errore ?
Avessi scritto:
SomeData* pData = GetValidData();
if (!pData) {
// Handle errors.
}
pData->Value = 42;
il funzionamento sarebbe stato lo stesso ?
Vi risparmio il cut & paste.
Nel primo snippet c'è una (volontaria) svista.
Non effettuo un test su pData ... ma un'assegnazione ed un test !!
Ho scritto "=" invece che "==", insomma.
Cosa che provoca l'assegnazione di NULL a pData, il test su pData (che però dà risultato opposto: pData vale 0, la condizione dell'if non è verificata) ed infine la dereferenziazione di un puntatore nullo. Access violation, ah ... bei tempi :-)
Sono quelle sviste che isolate in 3 righe si evidenziano subito, ma immerse in codice più complesso e articolato ti portano via ore di debug.
Ecco perchè, nonostante stilisticamente sia a mio giudizio peggiore, si scrive spesso:
if (NULL == pData)
In questo caso la svista non c'è. Ma se ci fosse stata, il compilatore ci avrebbe segnalato l'errore, perchè avremmo tentato di assegnare un valore ad una costante !
E in C# ?
Evidentemente la cosa non si pone, dal momento in cui sono valutate solamente le espressioni booleane !
Questo codice:
if (csValue = null)
generà un'errore in fase di compilazione (a meno di non aver ridefinito l'operatore di conversione implicita a Boolean !).
Siamo quindi protetti dalle nostre sviste, se volete.
E quindi liberi di adottare una convenzione di codifica più ... intuitiva.