In sostanza, i generici sono una tecnica per aiutare la separazione delle preoccupazioni, o il principio di responsabilità singola (SRP), così come il principio DRY (Non ripeterti). Senza generici, a volte si vedono nomi di tipi o metodi che fanno riferimento sia a un altro tipo sia a un'attività, ad esempio PersonCsvWriter
, CustomerRecordSearch
o ProductCollection
. Se questi tipi non derivano da altri tipi che separano queste responsabilità o ne consumano, allora stanno facendo due cose: ad es. PersonCsvWriter
converte Person
oggetti in insiemi di campi, e scrivono quei campi in un file CSV. Ciò rende più difficile il riutilizzo del codice. Se vedi questo tipo di cose, potrebbe essere un odore di codice che ti dice che i generici potrebbero essere usati.
Lo farei particolarmente se si definiscono interfacce o classi astratte. Le interfacce definiscono i ruoli nella tua applicazione e non hanno molto senso a meno che non ci possano essere più fornitori di quel ruolo. Se il ruolo è quello di lavorare con altri tipi e l'interfaccia non è generica, è molto difficile re-implementarla. Ad esempio, un IMapper<TFrom, TTo>
è ovviamente molto più riutilizzabile di un ICustomerToCustomerViewModelMapper
.
Ovviamente puoi essere genericamente generico trattando tutto come oggetti, usando la riflessione e / o il casting in fase di esecuzione (come ricorderanno i programmatori C # 1). Questo non è sicuro per il tipo, con l'ovvio inconveniente di rendere il tuo codice più difficile da eseguire il debug, consentendo di fallire in fase di runtime.