2010-06-30 7 views
6

Ho visto alcuni esempi in cui hanno trasformato una chiamata comeQuali sono i vantaggi dell'utilizzo di una chiamata generics-where-clause su una chiamata non generica?

void Add(IDrawing item); 

in

void Add<TDrawing>(TDrawing item) where TDrawing : IDrawing; 

Accanto ingannando l'intellisense nella visualizzazione del nome della classe invece del nome dell'interfaccia quando si chiama la funzione, a causa del tipo di utilizzo inferito in C# 4, ci sono altri vantaggi nell'usare il secondo approccio?

Per rispondere a Jon Skeet, il codice il nostro programmatore utilizzato è:

public ObservableCollection<IDrawing> Items { get; private set; } 

public void Add<TDrawing>(TDrawing item) where TDrawing : IDrawing 
{ 
    this.Items.Add(item); 
} 

Non vedo alcun vantaggio qui per l'utilizzo di un generico invece di utilizzare un parametro di tipo IDrawing. Presumo che ci debba essere un caso in cui è molto appropriato. Ero curioso di vedere se mi mancava qualcosa.

+0

"Oltre a ingannare l'intellisense nel mostrare il nome della tua classe" ... dannazione, non mi ero reso conto che sarebbe stato così, è quasi una ragione sufficiente per me voler usare il secondo approccio. – heisenberg

+0

Note secondarie secondarie: il termine .NET è "generici"; sono molto diversi dai "modelli" C++ o T4. –

+1

Aggiornato per utilizzare i generici. Mi dispiace, l'abitudine dei vecchi è vecchia. –

risposta

5

Dipende davvero da cosa succede in altre parti dell'implementazione. Ecco un altro esempio:

void Add<TDrawing>(TDrawing item, IList<TDrawing> list) 
    where TDrawing : IDrawing 
{ 
    if (item.SomePropertyOfIDrawing) 
    { 
     list.Add(item); 
    } 
} 

Ora non vorrebbe assumere un IList<IDrawing> qui - perché allora non si poteva usare se si ha un List<Painting> per esempio ... mentre con la versione generica di cui sopra, è assolutamente perfetto per TDrawing per essere Painting: il vincolo garantisce che la proprietà sia disponibile per la condizione if e il fatto che sia generica consente di aggiungere in modo sicuro l'elemento all'elenco.

Se si dispone di completo di esempi in cui non si ritiene che vi sia un vantaggio, varrebbe la pena presentarli in modo specifico.

MODIFICA: No, nell'esempio esatto ora dato non c'è alcun vantaggio nel renderlo un metodo generico.

+0

Infatti. Molto più utile a livello di una classe generica, in modo che l'intera classe abbia conoscenza di tipo basata sui vincoli generici. –

+0

Aggiungendo comunque qualcosa all'esempio originale (la necessità di mantenere entrambi i parametri dello stesso tipo) ... l'analogo all'esempio originale non passerebbe semplicemente all'elenco per IList ma anche TDrawing per elemento IDrawing. Voglio dire, è interessante e tutto, ma in realtà non risponde a quello che sta chiedendo. – heisenberg

+0

@kekekela: Originariamente il contesto non era sufficiente: ora c'è un esempio più completo, è più facile rispondere. –

1

pensare a questo scenario:

void Add<TDrawing>(TDrawing item, Func<TDrawing, bool> func) 
{ 
    //implementation 
} 

Ora, quando si chiama questo metodo, al momento della compilazione, sarete in grado di accedere ai proeprties specifici della specifica TDrawing essere passato in questo metodo da utilizzare con il Func .

0

La semantica della versione con la clausola "where" può essere molto diversa da quella senza quando una struct viene passata come parametro. Le posizioni di archiviazione (compresi i parametri) dei tipi di interfaccia contengono riferimenti all'oggetto heap. La forzatura del tipo di una struct che implementa un'interfaccia in un percorso di archiviazione di quel tipo di interfaccia creerà un nuovo oggetto heap con gli stessi campi e metodi della struct, copierà tutti i contenuti del campo (pubblico e privato) su quel nuovo oggetto e quindi memorizzerà un riferimento a quell'oggetto nella posizione di archiviazione. Al contrario, copiare una struttura in un'altra posizione di archiviazione di quel tipo di struttura copierà tutti i campi (pubblico e privato) ma lascerà il risultato come una struct, piuttosto che un oggetto heap.

Problemi correlati