2010-06-13 17 views
5

Vorrei sapere se (e in tal caso come) è possibile definire uno spazio dei nomi come parametro di vincolo in una dichiarazione di classe generica.Vincolo spazio dei nomi con dichiarazione di classe generica

Quello che ho è questa:

namespace MyProject.Models.Entities < - Contiene le mie lezioni da persistito nel db

namespace MyProject.Tests.BaseTest < - Ovvio penso

Ora la declassazione della mia classe 'BaseTest' sembra così;

public class BaseTest<T> 

Questo BaseTest fa poco di più (al momento della scrittura) di rimuovere tutti i soggetti che sono stati aggiunti al database durante il test. Così tipicamente avrò una classe di test dichiarato come:

public class MyEntityRepositoryTest : BaseTest<MyEntity> 

Quello che vorrei fare è qualcosa di simile al seguente:

public class BaseTest<T> where T : <is of the MyProject.Models.Entities namespace> 

Ora mi rendo conto che sarebbe stato del tutto possibile semplicemente dichiarare una classe 'BaseEntity' da cui erediteranno tutte le entità create nello spazio dei nomi MyProject.Models.Entities;

public class BaseTest<T> where T : MyBaseEntity 

ma ... In realtà non ho bisogno di, o voglio. Inoltre sto usando un ORM e mappando le entità con ereditarietà, anche se possibile, aggiungo uno strato di complessità che non è richiesto.

Quindi, è possibile vincolare un parametro di classe generico a uno spazio dei nomi e non un tipo specifico?

risposta

10

Non è possibile creare alcun vincolo di questo tipo per gli spazi dei nomi.

Una soluzione più preferibile sarebbe quella di rendere la classe generica internal anziché public. Ciò significa che la classe può essere solo creata direttamente e accessibile dalle classi nello stesso assembly (a meno che non si utilizzi l'attributo InternalsVisibleTo). Tuttavia, può essere indirettamente indirizzato (vale a dire come membro protetto/privato di una classe pubblica).

+0

Concordato. E, se il tipo che si desidera consentire è in un assembly diverso, consultare "InternalsVisibleToAttribute". Lo uso regolarmente con i test unitari in diversi gruppi. –

+0

Questo è un peccato, sono sorpreso che tu non possa fare qualcosa con espressioni lambda o qualcosa del genere. Non preoccuparti, quella soluzione "interna" soddisfa le mie esigenze a metà strada. Grazie per la guida. – SomeGuy

+0

@SomeGuy, per quanto ne so, lambdas è ancora solo una cosa runtime (tranne quando usato con le espressioni, ma anche in quel caso non sono eseguibili in fase di compilazione). Si è discusso se la potenziale funzione del compilatore C-5.0 del C# 5.0 possa consentire alcune personalizzazioni del compilatore, anche se dubito che lo vedremo mai. –

2

Il compilatore non eseguirà questo controllo. È tuttavia possibile verificare questo vincolo in fase di esecuzione, magari in un costruttore statico per il proprio tipo.

3

Un vincolo di spazio dei nomi non avrebbe alcun valore. Qualsiasi terza parte potrebbe creare una classe e inserire quella classe nello stesso spazio dei nomi.

Problemi correlati