Recentemente ho voluto arricchire una mia classe con un metodo dump per stampare a video i dati contenuti nell'oggetto. Volevo inoltre evitare di compilare questo metodo in release, rilegandolo quindi al debug.

Scrivo il mio metodello public string Dump() .... e mi chiedo, ed ora che uso? Un pragma o ConditionalAttribute? Opto per la seconda ed il compilatore di arrabbia parecchio, non vuole che il metodo abbia un valore di ritorno. Senza pormi problemi uso un bel #IF DEBUG ... #ENDIF e risolvo il problema. La giornata si conclude ma la domanda rimane. Vado a leggermi la documentazione e sembra proprio che i due approcci siano completamente intercambiabili.

Investigo maggiormente e noto che vi sono parecchie differenze quando siamo in condizioni in qui si esclude la condizione (scusate il gioco di parole). Iniziamo con la prima:

Usando il condizionale #IF ... #ENDIF il compilatore elimina il codice incluso in quell'area (proprietà, campi, metodi, ...) e se da qualche altra parte si fa uso di uno di quei metodi (proprietà, ...) il compilatore emette un errore compilazione.

ConditionalAttribute viceversa elimina anche tutte le chiamate a quel metodo (callsite) dalla compilazione. In altre parole se non è definito il simbolo DEBUG:

class Program {

[System.Diagnostics.Conditional("DEBUG")]
public static void Test() {
  System.Console.WriteLine("hello1");
}

static void Main(string[] args) {
  System.Console.WriteLine("hello");
  Test();
}
}

Non verranno compilati ne il metodo Test ne la sua chiamata. Per avere lo stesso comportamento con i pragma dovrei introdurre due #IF ..#ENDIF.

ConditionalAttribute si basa sulla callsite e non su metodo, diventa quindi ragionevole il perchè non sia accettabile avere un valore di ritorno. Basti immaginare che cosa succederebbe se avessimo:

class Program {

[System.Diagnostics.Conditional("DEBUG")]
public static string Test() {
  return "hello1";
}

static void Main(string[] args) {
  System.Console.WriteLine(Test());
}
}

In casi di funzioni ricordise, aggregazioni, ecc ecc rischieremmo di avere un programma vuoto oltre che la compilazione diverrebbe alquanto più lenta.

Risultato: bug segnalato nella documentazione.