2011-11-30 8 views
5

Ho un'interfaccia chiamata Identifiable<TId> che contiene un ID di proprietà singola del tipo specificato. Voglio creare una classe generica che prende uno di questi come parametro di tipo. Dovrebbe essere generico perché voglio restituire il tipo concreto, chiamare altri metodi generici dall'interno e usare cose come typeof(T).È possibile implementare questa interfaccia genericamente in modo che possa essere passato solo un parametro di tipo?

Questo funziona bene:

public class ClassName<T, TId> where T : Identifiable<TId> 

problema è che il codice chiamante deve passare in due tipi. per esempio. new ClassName<Person, int>()

Mi chiedo se in .net 3.5 ci sia un modo per scrivere questo in modo che TId possa essere dedotto da T? Permettendo al chiamante di fare solo new ClassName<Person>()?

+1

Forse si potrebbe mostrare un esempio un po 'più dettagliato in modo che possa sia chiaro cosa stai cercando di fare e perché. – deepee1

risposta

2

Dalla natura della tua domanda, immagino che il tuo ClassName non faccia affidamento su alcun metodo in Identificabile che richiede TId (altrimenti ti servirebbe il tipo.) Se è così, una soluzione comune in questo caso è quello di creare un'interfaccia di base non generica, con tutti i metodi che non richiedono il tipo di TId. Poi ci sono:

interface Identifiable<TId> : Identifiable //Not a standard interface name, btw 

e il vostro vincolo diventa:

public class ClassName<T> where T : Identifiable 

Supponendo che in realtà ha bisogno del tipo TiD, ma sta solo cercando di semplificare la sintassi di realizzazione, una possibilità, se il tuo costruttore sta prendendo un'istanza di Identificabile (come Persona nel tuo esempio) è per cambiare il costruttore con un metodo factory:

public static ClassName<T, TId> FromIdentifiable<T,TId>(T identifiable) where T: Identifiable<TId> 

Quanto sopra dovrebbe consentire al compilatore di dedurre i tipi e darvi una sintassi più breve, in base al tipo di parametro.

1

No. È necessario fornire un parametro di tipo per Identifiable<>; come si potrebbe fare che senza dichiarare il parametro nella dichiarazione della classe:

public class ClassName<T> where T : Identifiable<?WhatDoWePutHere?> 
1

per quanto ne so, non possibile con la clausola where. Potresti voler utilizzare i contratti di codice (ad esempio in .Net 4) e aggiungere

Contract.Requires(T is Identifiable<TId>); 

al tuo codice. Non so se ci sia un modo per far rispettare questo in. 3.5 3.5.

1

Se la maggior parte degli usi di vostra classe saranno di forma ClassName<Person, int> cui il tipo T (Persona) è quello che varia la maggior parte del tempo, ma il tipo di tid è quasi sempre int, si potrebbe fornire una classe parzialmente risolto che fornisce il TID digita ma mantiene il tipo T non associato. Lo svantaggio principale di questo è che avrete più classi che devono avere nomi diversi.

public class BaseClassName<T, TId> where T: Identifiable<TId> 
{ } 

public class ClassName<T> : ClassName<T, int> 
{ } 

var x = new ClassName<Person>(); 

Per il caso meno frequente quando non si vuole int come il TID, allora la classe arietà 2 è ancora disponibile:

var y = new BaseClassName<Person, int>() 
Problemi correlati