2010-06-13 8 views
5

Ich möchte wissen, ob (und wenn ja wie) es möglich ist, einen Namespace als Constraint-Parameter in einer generischen Klassendeklaration zu definieren.Namespace-Einschränkung mit generischer Klassendeklaration

Was ich habe, ist dies:

namespace MyProject.Models.Entities < - Enthält meine Klassen in db werden beharrte

namespace MyProject.Tests.BaseTest < - Offensichtliche ich denke

Nun sieht die Deklaration meiner BaseTest-Klasse so aus; Diese

public class BaseTest<T> 

BaseTest tut wenig mehr (zum Zeitpunkt des Schreibens) als alle Elemente entfernen, die in die Datenbank während des Tests hinzugefügt wurden. So normalerweise werde ich eine Testklasse haben erklärt, wie:

public class MyEntityRepositoryTest : BaseTest<MyEntity> 

Was Ich mag würde, ist etwas zu tun, ähnlich der folgenden:

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

Nun ich weiß, dass es durchaus möglich wäre, einfach eine "BaseEntity" -Klasse deklarieren, von der alle im Namespace MyProject.Models.Entities erstellten Entitäten erben;

public class BaseTest<T> where T : MyBaseEntity 

aber ... ich brauche nicht wirklich, oder will. Außerdem verwende ich ein ORM und Mapping-Entitäten mit Vererbung, obwohl möglich, fügt eine Schicht von Komplexität hinzu, die nicht erforderlich ist.

Ist es also möglich, einen generischen Klassenparameter auf einen Namespace und nicht auf einen bestimmten Typ zu beschränken?

Antwort

10

Es ist nicht möglich, solche Einschränkungen für Namespaces zu erstellen.

Eine bevorzugtere Abhilfe wäre, Ihre generische Klasse internal statt public zu machen. Dies bedeutet, dass die Klasse nur direkt instanziiert und von Klassen in derselben Baugruppe zugegriffen werden kann (es sei denn, Sie verwenden das Attribut InternalsVisibleTo). Es kann jedoch immer noch indirekt instanziiert werden (d. H. Als geschütztes/privates Mitglied einer öffentlichen Klasse).

+0

Einverstanden. Und wenn der Typ, den Sie zulassen möchten, sich in einer anderen Assembly befindet, dann schauen Sie in 'InternalsVisibleToAttribute' nach. Ich verwende dies regelmäßig mit Unit Tests in verschiedenen Baugruppen. –

+0

Das ist eine Schande, ich bin überrascht, dass Sie etwas mit Lambda-Ausdrücke oder etwas nicht tun können. Keine Sorge, diese "interne" Lösung erfüllt meine Bedürfnisse auf halbem Wege. Danke für die Anleitung. – SomeGuy

+0

@SomeGuy, soweit ich weiß, sind lambdas immer noch nur eine Laufzeit-Sache (außer bei Verwendung mit Expressions, aber selbst dann sind sie zur Kompilierzeit nicht ausführbar). Es gab einige Diskussionen darüber, ob der zukünftige C# 5.0-Compiler-as-a-Service-Feature eine Anpassung des Compilers erlauben könnte, obwohl ich meine Zweifel habe, ob wir das jemals sehen werden. –

2

Der Compiler führt diese Überprüfung für Sie nicht durch. Sie können diese Einschränkung jedoch zur Laufzeit überprüfen, möglicherweise in einem statischen Konstruktor für Ihren Typ.

3

Eine Namespace-Einschränkung hat keinen Wert. Jede dritte Partei könnte eine Klasse erstellen und diese Klasse in denselben Namespace einfügen.

Verwandte Themen