Quali problemi possono essere risolti usando Generics?

4

Non ho usato Generics in C # per molto tempo. Ogni volta che penso di aver bisogno di usarli, o vado nella direzione sbagliata e rinuncio o trovo che non ne ho veramente bisogno. Sento che mi sto perdendo o ignorando una tecnica che potrebbe essere utile e potente.

Sono consapevole di come i generici devono essere usati (o almeno penso di essere). Se hai tre metodi che fanno tutti la stessa cosa con tipi diversi, usare i generici ti consente di avere un solo metodo che funzionerà con questi tre tipi.

MODIFICA (in risposta al commento)

Ci sono odori o schemi di codice che dovrei cercare?

Nota Io uso List<> molto, quindi non sto ignorando i generici nella libreria standard. È solo che non ho scritto codice personalizzato usando Generics per un po '.

    
posta Daniel Hollinrake 20.03.2013 - 12:43
fonte

5 risposte

7

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.

    
risposta data 20.03.2013 - 13:15
fonte
9

In breve, i generici risolvono il problema di dover utilizzare oggetti con caratteri generici.

Ad esempio, considera ArrayList rispetto a List<T> . Ti permette di avere una collezione strongmente tipizzata. list[0] restituirà il tipo T rispetto a arrayList[0] che restituirà il tipo object .

Ma puoi fare di più con i generici che con le sole raccolte. Considera un repository generico utilizzato in una soluzione relazionale di oggetti:

public class Repository<T> where T : class, IBusinessOBject
{
  T Get(int id)
  void Save(T obj);
  void Delete(T obj);
}

I generici possono consentire alla tua classe di incapsulare vari tipi senza richiedere modifiche al livello di origine.

    
risposta data 20.03.2013 - 13:01
fonte
4

Questo è divertente perché mi trovo a scrivere classi e operazioni generiche tutto il tempo. Forse perché sto lavorando più sul codice a livello di struttura che sul lato client. Alcuni esempi includono Repository generici Event Aggregators e CQRS Command Handlers , tra gli altri.

I generici sono per lo più utili nel codice a livello di struttura per consentire il riutilizzo. Se stai solo consumando i framework, potresti non trovarti a creare funzioni generiche.

    
risposta data 20.03.2013 - 15:22
fonte
2

A meno che tu non stia programmando in Ada, dove viene sempre in mente, l'opportunità di creare un nuovo codice generico è abbastanza rara. Per me, si presenta forse una volta ogni tre o cinque anni, abbastanza a lungo che devo cercare la sintassi.

Il modo per dirti che ne hai bisogno è quando ti ritrovi a copiare e incollare il codice, modificare solo i tipi e provare a risolverlo usando l'ereditarietà e non aiuta.

    
risposta data 20.03.2013 - 13:32
fonte
1

Come Microsoft dice (e altri hanno detto nei commenti), il posto più comune utilizzare generics è quando si desidera definire un'operazione su un elenco di oggetti, ma non preoccuparsi troppo dei tipi specifici degli oggetti nell'elenco.

L'esempio classico è l'ordinamento di un elenco.

Un odore di codice che probabilmente indica che l'uso di generici può migliorare è ( di Jeff Atwood ):

    
risposta data 20.03.2013 - 13:00
fonte

Leggi altre domande sui tag