Coding Horror #2

Some time ago I started writing a series of blog post (only one for precision) about some “absurd” code I meet in my daily work.

I called this series “Coding horror”, and, so far I have written only one post, this one.

This is the second one.

About the code below, I thing that every comment is unnecessary because it speaks for itself.

if (myVar == null)
    return myVar = null;

As an additional reason, the Resharper tooltip about the row number 2 is:

“Destination has the same value before assignment”.

It could not be much clearer than that.

Technorati Tags:

Link utili della settimana #8

Super cool MSBuild Debugging in Visual Studio IDE
Questa è una feature eccezionale non ufficialmente supportata. Seguendo il link è possibile scoprire i passi necessari per abilitarla in Visual Studio 2010.

Tool di migrazione VB6 –> VB .NET / C# gratuito
Considerato che è gratuito e che promette bene vale sicuramente la pena provarlo.

Visual Studio 2010 Dark background
Add-in per VS 2010 per impostare dei temi personalizzati circa i colori, tra cui un fantastico Dark

Microsoft ADO .NET Entity Framework Feature CTP4

– Domain Driven Design di Alberto Brandolini  Part 1; Part 2; Part 3

Domain Model Pattern (Martin Fowler)

ASP.NET Multi-Level Drop Down Menu – JQuery

NUnit Result Manager
Web application per tener traccia dei risultati degli unit tests (per project manager & developer)

Uso delle parentesi graffe

Sono sempre stato piuttosto “maniacale” nella scrittura di codice, circa il rispetto delle guidelines e circa uno stile di codifica che aiuti a migliorare la leggibilità dello stesso, e la sua manutenibilità.

Ho sempre sostenuto che il pezzo di codice scritto stilisticamente bene è quello che si “autodocumenta” semplicemente solo leggendolo.

La leggibilità aumenta, a mio parere, anche con opportuni accorgimenti o tecniche, non sempre utilizzati da tutti, anzi spesso ci sono pareri discordanti sull’effettiva utilità di alcune modalità di scrittura.

Mi riferisco, ad esempio, all’utilizzo delle parentesi graffe in alcuni casi particolari dove possono essere evitate (ovviamente il contesto è quello di applicazione scritta in C#, linguaggio principe nel mondo .Net).

A mio avviso, la leggibilità beneficia del fatto di scrivere qualcosa del genere:

if (condizione)
    a = 1;

rispetto a questo codice:

if (condizione)
   {
     a = 1;
   }

Quando mi ritrovo a svolgere code review oppure solo a guardare codice scritto da altri, la tentazione di eliminare le graffe è troppo forte, e, quando posso, finisco per toglierle.

La stessa tecnica la applico al ciclo for, ovviamente anche in questo caso l’istruzione da eseguire deve essere una sola.

Circa le if, sarebbe addirittura più valida l’idea di toglierle proprio, in perfetta aderenza ai principi della campagna anti-if, a cui ho aderito con entusiasmo, anche se qui il contesto è differente poichè le “if” andrebbero usate con parsimonia o evitate del tutto quando particolarmente annidate e ripeture (così come l’istruzione “switch”),  sostituendole con una applicazione più rigorosa dei principi della programmazione ad oggetti, polimorfismo ed ereditarietà in primis.

Rilevare codice duplicato

Clone Detective for Visual Studio è una integrazione dell’ambiente Visual Studio (completamente free) in gradi di rilevare porzioni di codice duplicato tra i vari progetti che compongono una solution. Il fine è ambizioso, poichè come dice la stessa presentazione del prodotto presente su CodePlex

“Having duplicates can easily lead to inconsistencies and often is an indicator for poorly factored code”

Un componente del genere può davvero essere utilissimo, anche oltre lo scopo che si prefigge. Ad esempio, conoscendo accuratamente il numero di cloni presenti all’interno di un software con parecchie linee di codice, è possibile valutarne il costo di manutenzione, ovvero il costo a cui si va incontro se si decidesse di apportarvi delle modifiche.

Il componente si basa su ConQAT (Continuous Quality Assessment Toolkit) per rilevare le parti di codice duplicato. Questo toolkit fornisce una serie di tools e linee guida per il controllo della qualità del software

Metodi virtuali nel costruttore

Tra le guidelines da seguire circa la scrittura del costruttore di una classe questa assume una certa importanza:

Evitare di richiamare all’interno di un costruttore un metodo virtuale.

Questa guidelines è dovuta al fatto che in presenza di un metodo che ridefinisce un metodo virtuale (ne fa l’override insomma), viene richiamato sempre il metodo esposto dalla classe derivata, ovvero il metodo più specifico della implementazione, a prescindere se il costruttore della classe che espone il metodo derivato sia stato richiamato.  L’esempio sotto, tratto dalla documentazione MSDN, chiarisce bene questo concetto.

La creazione della classe DerivedFromBad, cioè il richiamo del suo costruttore, provoca la chiamata immediata  al costruttore della sua classe di base, ovvero BadBaseClass, il quale prima inizializza una variabile (state) e poi richiama il metodo virtuale SetState. Peccato che poiche l’oggetto che si sta cercando di costruire (DerivedFromBad) ridefinisce il metodo SetState, all’interno del costruttore della classe BaseClass il metodo effettivamente chiamato è l’implementazione fornita dalla classe DerivedFromBad, e non quella della classe base BadBaseClass. L’esecuzione  del metodo ridefinito SetState avviene a prescindere se il costruttore della classe derivata sia o no stato richiamato. In questo caso, poiche non  viene richiamato, l’inizializzazione della variabile state non  avviene ed il suo contenuto resta fermo a quello impostato dalla classe base, ovvero “BadBaseClass“.

 public class tester
 {
     public static void Main()
     {
         DerivedFromBad b = new DerivedFromBad();
     }
 }
      
 public class BadBaseClass
 {
      protected string state;
      public BadBaseClass()
      {
          state = "BadBaseClass";
          SetState();
      }
      public virtual void SetState()
      {
 
      }
 }
   
 public class DerivedFromBad : BadBaseClass
 {
      public DerivedFromBad()
      {
        state = "DerivedFromBad ";
      }
      public override void SetState()
      {
        Console.WriteLine(state);
      }
 }