Technology Experience
.NET World

Classi statiche & generics: un comportamento da tener presente!

Date un’occhiata alla seguente classica statica:

1 public static class DataProvider<T> where T : new() 2 { 3 private static bool init; 4 5 static void initialize() 6 { 7 init = true; 8 } 9 10 public static void MakeSomeOperation() 11 { 12 if (!init) initialize(); 13 } 14 }

Estratto da un data provider che ho sviluppato tempo fa.
E’ una classe statica DataProvider che fa uso di un generics <T>. Ha una proprietà statica booleana Init, che utilizza un field privato init. L’unico metodo presente è MakeSomeOperation(), statico anch’esso, che prima di fare qualcosa controlla se la classe è già stata inizializzata. Nulla di strano, giusto?

La morale però è questa: la prima volta che utilizzo questa classe chiamando il metodo pubblico MakeSomeOperation(), entro nel piccolo blocco if e quindi viene eseguita la initialize() privata. Poi init viene impostata a true, per cui pensavo stupidamente di non passare più dalla procedura di inizializzazione. Cosa che non è affatto vera. Per esempio, con il codice seguente…

DataProvider<ArrayList>.MakeSomeOperation(); DataProvider<ArrayList>.MakeSomeOperation(); DataProvider<StringBuilder>.MakeSomeOperation();

…utilizzo tre volte la classe DataProvider. Le prime due chiamate usano T come se fosse un ArrayList; la terza ed ultima chiamata usa T come se fosse uno StringBuilder. Ho dovuto usare due classi con il costruttore vuoto, dato il constraint applicato al generics.

Alla prima chiamata (ArrayList) avviene l’inizializzazione.
Alla seconda chiamata (ArrayList) l’inizializzazione non avviene più.
Alla terza chiamata (StringBuilder) l’inizializzazione viene eseguita ancora una volta.

Ogni volta che cambio il Type assunto da T, la classe statica DataProvider viene reistanziata per quel particolare tipo, e quindi viene nuovamente scatenata l’esecuzione di initialize(). Ci sarebbe un modo per evitarlo, cioè spostare la definizione del generics dal nome della classe al nome del metodo. Però, ovviamente, dipende da quello che dobbiamo fare, mica è detto che debba per forza sempre essere così!

Technorati Tags:  

Send to Kindle

Igor Damiani

La sua passione per l'informatica nasce nella prima metà degli anni '80, quando suo padre acquistò un Texas Instruments TI-99. Da allora ha continuato a seguire l'evoluzione sia hardware che software avvenuta nel corso degli anni. E' un utente, un videogiocatore ed uno sviluppatore software a tempo pieno. Igor ha lavorato e lavora anche oggi con le più moderne tecnologie Microsoft per lo sviluppo di applicazioni: .NET Framework, XAML, Universal Windows Platform, su diverse piattaforme, tra cui spiccano Windows 10 piattaforme mobile. Numerose sono le app che Igor ha creato e pubblicato sul marketplace sotto il nome VivendoByte, suo personale marchio di fabbrica. Adora mantenere i contatti attraverso Twitter e soprattutto attraverso gli eventi delle community .NET.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.