2012-09-07 9 views
10

tengo las siguientes clases/interfaces:C# Restricción genérica - ¿Cómo hacer referencia al tipo de clase actual?

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 {} 

¿Hay alguna manera de que pueda constreñir TP en IView <> a ser una clase que hereda de AbstractBasePresenter?

¿O es mi única alternativa para crear una interfaz IPresenter no genérica y luego actualizar IPresenter para implementarla y luego usar la verificación "TP: IPresenter"?

Gracias

Actualización:

respuesta se proponen a continuación no funciona:

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

He interfaz declarado:

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

public interface IInsuredDetailsPresenter : IPresenter<IInsuredDetailsView> 
{ } 

compilador se queja de que IInsuredDetailsPresenter no es asignable a AbstractBasePresenter>

+0

'AbstractBasePresenter' con qué' T'? C# no tiene ningún concepto de instancias de tipos genéricos para los que no se hayan establecido algunos parámetros de tipo. –

+0

'donde TP: AbstractBasePresenter >' compila, pero no estoy seguro de que proporcione el resultado que desee ... – nemesv

+1

Como observación, la siguiente estructura es muy complicada y es difícil de entender lo que puede ser útil para. – Andrey

Respuesta

2

Puede hacerlo, pero hay que dar un argumento más tipo a la IView<> interfaz:

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

Editar:

De acuerdo con ediciones en su pregunta: IInsuredDetailsPresenter definitivamente no es asignable a AbstractBasePresenter. El compilador se queja debido a la restricción que solicitó en su pregunta original. Más específicamente, debido a esta parte

where TP : AbstractBasePresenter<T> 

Parece desea limitar TP a ser una interfaz también. Usted puede tratar de la pieza por debajo de código:

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

Restricciones en T no más se necesitan, porque IPresenter<T> no tiene ninguna. Por supuesto, podría adaptar la respuesta de armen.shimoon de manera similar. El punto es reemplazar la restricción AbstractBasePresenter<T> con la restricción IPresenter<T>.

+0

Tu código no se compila. Te falta un 'donde T: IView' – nemesv

+0

@nemesv: Es cierto, gracias – pbalaga

+0

No creo que necesites agregar el cuarto parámetro genérico. –

4

No hay problema, sin necesidad de otro parámetro genérico:

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

Editar: Actualización pregunta:

Si usted no necesita el presentador de heredar de AbstractBasePresenter, cambie el código para:

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

Su solución es buena dado que no se necesita un soporte de tipo fuerte al máximo. (No tiene control de qué tipo es exactamente la 'T' en' AbstractBasePresenter'.) – pbalaga

+1

Esto no funciona. Ver la pregunta editada arriba. – Rezler

Cuestiones relacionadas