2012-09-07 9 views
10

Ich habe folgende Klassen/Schnittstellen:C# Generic Constraint - Wie verweist man auf den aktuellen Klassentyp?

public abstract class AbstractBasePresenter<T> : IPresenter<T> 
    where T : class, IView 
{ 
} 

public interface IPresenter<T> 
{ 
} 

public interface IView<TV, TE, TP> : IView 
    where TV : IViewModel 
    where TE : IEditModel 
    //where TP : AbstractBasePresenter<???> 
{ 
} 

public interface IView {} 

Gibt es eine Möglichkeit, die ich TP auf IView <> beschränken kann eine Klasse sein, die von AbstractBasePresenter erbt?

Oder ist meine einzige Alternative, um eine nicht-generische IPresenter-Schnittstelle zu erstellen und dann IPresenter zu aktualisieren, um es zu implementieren, und verwenden Sie dann prüfen "TP: IPresenter"?

Dank

Update:

Vorgeschlagene Antwort unten nicht funktioniert:

public interface IView<TV, TE, TP> : IView 
where TV : IViewModel 
where TE : IEditModel 
where TP : AbstractBasePresenter<IView<TV,TE,TP>> 
{ 
} 

Ich habe Schnittstelle deklariert als:

public interface IInsuredDetailsView : IView<InsuredDetailsViewModel, InsuredDetailsEditModel, IInsuredDetailsPresenter> 
{ } 

public interface IInsuredDetailsPresenter : IPresenter<IInsuredDetailsView> 
{ } 

Compiler beschwert sich, dass IInsuredDetailsPresenter nicht übertragbar ist AbstractBasePresenter>

+0

'AbstractBasePresenter' mit was' T'? C# hat kein Konzept von Instanzen generischer Typen, für die einige Typparameter nicht festgelegt wurden. –

+0

'wo TP: AbstractBasePresenter >' Kompiliert, aber ich bin mir nicht sicher, dass es das Ergebnis liefern wird, was Sie wollen ... – nemesv

+1

Als eine Bemerkung ist die folgende Struktur überkompliziert und es ist schwer zu verstehen, was es sein kann nützlich zum. – Andrey

Antwort

2

Sie können es tun, aber Sie müssen eine weitere Art Argument für die IView<> Schnittstelle zur Verfügung zu stellen:

public interface IView<TV, TE, TP, T> : IView 
    where TV : IViewModel 
    where TE : IEditModel 
    where TP : AbstractBasePresenter<T> 
    where T : class, IView 
{ 
} 

Edit:

Nach Ausgaben in Ihrer Frage: IInsuredDetailsPresenter ist auf jeden Fall nicht übertragbar zu AbstractBasePresenter. Compiler beschweren sich aufgrund der Einschränkung, die Sie in Ihrer ursprünglichen Frage angefordert haben. Insbesondere aufgrund

where TP : AbstractBasePresenter<T> 

Es scheint, Sie zu diesem Teil wollen TP begrenzen sowie eine Schnittstelle zu sein. Sie können die unten Stück Code versuchen:

public interface IView<TV, TE, TP, T> : IView 
    where TV : IViewModel 
    where TE : IEditModel 
    where TP : IPresenter<T> 
{ 
} 

Constraints auf T werden nicht mehr benötigt, da IPresenter<T> keine hat. Natürlich könnte man armens.shimoon's Antwort in ähnlicher Weise anpassen. Der Punkt ist AbstractBasePresenter<T> Einschränkung mit IPresenter<T> Constraint zu ersetzen.

+0

Ihr Code wird nicht kompiliert. Sie vermissen ein 'where T: IView' – nemesv

+0

@nemesv: True, danke – pbalaga

+0

Ich glaube nicht, dass Sie den vierten generischen Parameter hinzufügen müssen. –

4

Kein Problem, keine Notwendigkeit für einen anderen generischen Parameter:

public interface IView<TV, TE, TP> : IView 
    where TV : IViewModel 
    where TE : IEditModel 
    where TP : AbstractBasePresenter<IView<TV,TE,TP>> 
{ 
} 

Edit: Aktualisiert Frage:

Wenn Sie von AbstractBasePresenter nicht den Moderator müssen erben, um den Code ändern:

public interface IView<TV, TE, TP> : IView 
    where TV : IViewModel 
    where TE : IEditModel 
    where TP : IPresenter<IView<TV,TE,TP>> 
{ 
} 
+0

Ihre Lösung ist gut, da stark typisierte Unterstützung nicht in vollem Umfang benötigt wird. (Sie haben keine Kontrolle darüber, welcher Typ genau das "T" in "AbstractBasePresenter" ist.) – pbalaga

+1

Dies funktioniert nicht. Siehe bearbeitete Frage oben. – Rezler

Verwandte Themen