2012-09-07 10 views
10

ho le seguenti classi/interfacce:C# Vincolo generico - Come fare riferimento al tipo di classe corrente?

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

C'è un modo che io possa costringo TP su IView <> per essere una classe che eredita da AbstractBasePresenter?

Oppure è la mia unica alternativa per creare un'interfaccia IPresenter non generica e quindi aggiornare IPresenter per implementarlo e quindi utilizzare il controllo "TP: IPresenter"?

Grazie

Aggiornamento:

soluzione proposta di seguito non funziona:

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

Ho interfaccia dichiarata come: lamenta

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

public interface IInsuredDetailsPresenter : IPresenter<IInsuredDetailsView> 
{ } 

compilatore che IInsuredDetailsPresenter non è cedibile a AbstractBasePresenter>

+0

'AbstractBasePresenter' con quale' T'? C# non ha concetto di istanze di tipi generici per i quali alcuni parametri di tipo non sono stati impostati. –

+0

'dove TP: AbstractBasePresenter >' compila ma non sono sicuro che fornirà il risultato ciò che vuoi ... – nemesv

+1

Come nota, la seguente struttura è complicata ed è difficile capire cosa può essere utile per. – Andrey

risposta

2

Si può fare, ma è necessario fornire più un tipo di argomento all'interfaccia IView<>:

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

Edit:

Secondo edizioni in vostra domanda: IInsuredDetailsPresenter è sicuramente non assegnabile a AbstractBasePresenter. Il compilatore si lamenta a causa del vincolo che hai richiesto nella tua domanda originale. Più in particolare a causa di questa parte

where TP : AbstractBasePresenter<T> 

Sembra si desidera vincolare TP di essere un'interfaccia pure. Puoi provare il pezzo di sotto di codice:

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

Vincoli T non di più sono necessari, perché IPresenter<T> ha nessuno. Naturalmente, è possibile adattare la risposta di armen.shimoon in un modo simile. Il punto è sostituire il vincolo AbstractBasePresenter<T> con il vincolo IPresenter<T>.

+0

Il tuo codice non viene compilato. Ti manca un 'dove T: IView' – nemesv

+0

@nemesv: True, grazie – pbalaga

+0

Non penso che sia necessario aggiungere il quarto parametro generico. –

4

Nessun problema, c'è bisogno di un altro parametro generico:

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

Edit: domanda Aggiornato:

Se non è necessario il presentatore di ereditare da AbstractBasePresenter, modificare il codice per:

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

La soluzione è buona poiché non è necessario il supporto fortemente tipizzato. (Non hai il controllo di quale tipo è esattamente il 'T' in 'AbstractBasePresenter'.) – pbalaga

+1

Questo non funziona. Vedi la domanda modificata sopra. – Rezler

Problemi correlati