2010-06-13 4 views
5

Je voudrais savoir si (et si oui comment) il est possible de définir un espace de noms en tant que paramètre de contrainte dans une déclaration de classe générique.Contrainte d'espace de noms avec déclaration de classe générique

Ce que j'est ceci:

namespace MyProject.Models.Entities < - Contient mes classes à persisté dans db

namespace MyProject.Tests.BaseTest < - Je pense que Obvious

Maintenant, la déchiffrement de ma classe "BaseTest" ressemble à cela;

public class BaseTest<T> 

Ce BaseTest ne fait guère plus (au moment de la rédaction) que supprimer toutes les entités qui ont été ajoutées à la base de données au cours des essais. Donc, en général, je suis une classe de test déclarée comme:

public class MyEntityRepositoryTest : BaseTest<MyEntity> 

Ce que je voudrais faire est quelque chose de semblable à ce qui suit:

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

Maintenant, je sais que ce serait tout à fait possible de simplement déclarez une classe 'BaseEntity' à partir de laquelle toutes les entités créées dans l'espace de noms MyProject.Models.Entities hériteront;

public class BaseTest<T> where T : MyBaseEntity 

mais ... Je n'ai pas vraiment besoin de, ou je ne veux pas. De plus j'utilise un ORM et mappage d'entités avec héritage, bien que possible, ajoute une couche de complexité qui n'est pas requise.

Alors, est-il possible de contraindre un paramètre de classe générique à un espace de noms et non à un type spécifique?

Répondre

10

Il n'est pas possible de créer de telles contraintes pour les espaces de noms.

Une solution de contournement plus préférable serait de faire votre classe générique internal plutôt que public. Cela signifie que la classe peut uniquement être directement instanciée et accédée par les classes du même assembly (sauf si vous utilisez l'attribut InternalsVisibleTo). Cependant, il peut toujours être indirectement instancié (c'est-à-dire en tant que membre protégé/privé d'une classe publique).

+0

D'accord. Et, si le type que vous voulez autoriser est dans un assemblage différent, regardez dans 'InternalsVisibleToAttribute'. J'utilise cela avec des tests unitaires dans différents assemblages régulièrement. –

+0

C'est une honte, je suis surpris que vous ne pouvez pas faire quelque chose avec des expressions lambda ou quelque chose. Ne vous inquiétez pas, cette solution "interne" répond à mes besoins à mi-chemin. Merci pour les conseils. – SomeGuy

+0

@SomeGuy, pour autant que je sache, les lambdas ne sont encore qu'une chose d'exécution (sauf quand ils sont utilisés avec des Expressions, mais même alors ils ne sont pas exécutables au moment de la compilation). Il y a eu une discussion pour savoir si la fonction de compilateur en tant que service C# 5.0 pourrait permettre une certaine personnalisation du compilateur, bien que j'aie des doutes si nous le verrons jamais. –

2

Le compilateur n'exécutera pas cette vérification pour vous. Vous pourriez cependant vérifier cette contrainte au moment de l'exécution, peut-être dans un constructeur statique pour votre type.

3

Une contrainte d'espace de nom serait sans valeur. Tout tiers pourrait créer une classe et placer cette classe dans le même espace de noms.

Questions connexes