Questo post inizia con una frase tratta da un post di Scott Hanselmann con cui mi trovo completamente d’accordo:
Don’t believe everything you read, even on a Microsoft Blog.
Don’t believe this blog, either!
Decide for yourself with experiments if you need a tiebreaker!
Credo sia proprio vero, mai fidarsi ciecamente di quello che si legge in giro, soprattutto quando seri dubbi farebbero pensare il contrario.
Il motivo è presto detto: utilizzo normalmente FxCop come strumento di analisi del codice sorgente, lo trovo molto completo e ben fatto. Spinto dalla curiosità ho voluto utilizzare Source Analysis, un tool gratuito fornito da Microsoft ed integrato nell’IDE di Visual Studio. Dopo la primissima prova fatta mi ha incuriosito una sua segnalazione:
SA1200 – All using directives must be placed inside of the namaspace.
Per farla breve, tutti i files sorgenti del mio progetto provocavano una segnalazione di questo tipo poichè le direttive using erano poste esternamente alla definizione del namespace, così come automaticamente viene creato uno scheletro di una classe all’interno dell’IDE. La segnalazione in questione invita invece ad includere le direttive using all’interno della definizione del namespace, semprecchè sia presente. Facendo qualche ricerca in giro ho scoperto che in questo modo il compilatore segnala immediatamente una eventuale ambiguità tra i nomi dei tipi creati all’interno del proprio namespace e i tipi presenti nei vari namespace del .NET Framework. E fin qui nulla di strano.
Ho scoperto inoltre che questa guideline servirebbe anche ad aumentare le prestazioni, almeno nei casi specifici, in quanto forzarebbe il “lazy loading” degli assembly e non il caricamento immediato. In altre parole, quando il viene invocato un metodo di una classe e viene compilato il codice “just in time” (JITTED) il lazy loading permette di caricare in memoria solo gli assembly referenziati che servono all’invocazione del metodo stesso, e non tutti gli assembly referenziati da una classe, a prescindere se utilizzati o no da una specifica invocazione di un metodo. Questo permette di caricare solo lo stretto necessario anche se una classe referenzia un assemby non utilizzato da un metodo.
Sinceramente non mi è venuto in mente un solo valido motivo per cui una direttiva using posta in un certo modo potesse influenzare l’attività del CRL a runtime, e sono rimasto alquanto dubbioso sulla effettiva validità. Prima che potessi avere il tempo di fare una prova specifica mi son trovato questo post di Scott Hanselmann, al quale rimando per una esauriente spiegazione, che dimostra come purtroppo ciò non sia affatto vero, cioè gli assembly referenziati vengono caricati tutti i memoria immediatamente, a prescindere se il metodo in questione li usa oppure no, ed a prescindere se le direttive using vengono poste all’interno o all’esterno della definizione di namespace.
Quindi la morale è: non credere mai a quello che leggi, neanche se lo leggi da questo blog :), ma sperimenta sempre.