Uso improprio dei generics

di Cristian Civera, in .NET 3.5,

I generics sono tanto belli bellini. Senza di essi non esisterebbe LINQ, gli extension method non avrebbero trovato così ampio spazio e non potremmo scrivere classi generiche utilizzabili per più tipi.

Ci sono alcune pratiche però che mi capitano di vedere e io non ritengo corrette. Per esempio capita di vedere metodi che accettano un tipo generico ed effettuano un cast al loro interno, celandolo al chiamante:

public static T GetValue<T>()
{
    object obj = ....;
    return (T)obj;
}

L'esempio è banale, ma sufficiente per illustrare il mio dubbio. I generics son nati per tipizzare e migliorare anche in performance (evitano cast e box/unbox). Nel passato si usava un ArrayList e la cosa principalmente brutta era non avere una tipizzazione e si rischiava di cadere in InvalidCastException. Con i generics questo problema è stato risolto. Ciò che non mi piace del codice precedente è che celiamo al chiamante il fatto che io faccio un cast e per chi usa questo metodo sembra tutto sicuro e tipizzato.
In LINQ to DataSet hanno messo l'extesion method Field<T> che data la colonna ti restituisce il valore tipizzato, così:

int c = row.Field<int>("colonna")

Qual'è la differenza rispetto a quest'altro codice?

int c = (int)row["colonna"]

Di fatto nessuna. Entrambi sono potenzialmente vittime di un InvalidCastException, solo che il primo codice è stilisticamente più bello da vedere. Non trovate? Ormai avere un cast nel codice è come avere qualcosa di sporco e infatti nella maggior parte dei casi secondo me è così. Con l'extension method generic hanno reso più bello il codice, ma di fatto il problema resta.
E' vero che nella documentazione c'è giustamente scritto che tra le probabili eccezioni c'è tale eccezione, ma a questo punto allora mi domando: perché implementare un metodo del genere?

Viceversa trovo molto bello l'uso dei metodi generic per effettuare downcast. Per esempio:

public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
{
    return source;
}

In questo caso non viene coinvolto nessun cast, cosa che dovrei usare (seppure in modo sicuro) se non avessi questo metodo, ma semplicemente diciamo al compilatore su che tipo riferirsi se poi eventualmente chiamiamo altri metodi.

Ok, ci sono problemi ben più seri nella vita, ma comunque rendo pubblica questa mia riflessione.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese