2009-12-29 7 views
3

J'ai la structure de classe suivante:.net 4 génériques question

public class A : AInterface { } 
public interface AInterface { } 

public class B<T> : BInterface<T> where T : AInterface 
{ 
    public T Element { get; set; } 
} 
public interface BInterface<T> where T : AInterface 
{ 
    T Element { get; set; } 
} 

public class Y : B<A> { } 

public class Z<T> where T : BInterface<AInterface> {} 

public class Test 
{ 
    public Test() 
    { 
     Z<Y> z = new Z<Y>(); 
    } 
} 

Cela me donne les éléments suivants dans la compilation erorr C# 4.0. Le type 'Test.Y' ne peut pas être utilisé comme paramètre de type 'T' dans le type générique ou la méthode 'Test.Z'. Il n'y a pas de conversion de référence implicite de 'Test.Y' à 'Test.BInterface'.

Je pense que la covariance dans les génériques devrait faire ce travail? Toute aide serait appréciée.

Répondre

4

Les paramètres génériques dans les interfaces sont invariants par défaut, vous devez spécifier explicitement si vous souhaitez qu'un paramètre générique particulier soit covariant ou contravariant. En fait, dans votre exemple, vous devez ajouter le mot clé « out » à la déclaration d'interface:

public interface BInterface<out T> where T : AInterface { } 

Vous pouvez trouver plus d'informations sur la création d'interfaces variantes sur MSDN: Creating Variant Generic Interfaces (C# and Visual Basic).

+0

Merci Alexandra. Cela aiderait certainement si T est un paramètre de retour. Dans mon cas, je l'ai manqué un détail important dans le B et BInterface: public class B : BInterface où T: AInterface { publique T Element {get; ensemble; } } interface publique BInterface où T: AInterface { T Elément {get; ensemble; } } ne fonctionnera pas puisque T est à la fois dedans et dehors. Aucune suggestion? – roger

+0

Oui, si vous avez une contrainte générique sur un paramètre de type, vous ne pouvez pas le rendre covariant. C'est par conception. http://msdn.microsoft.com/en-us/library/dd469487(VS.100).aspx "Dans une interface générique, un paramètre de type peut être déclaré covariant s'il satisfait aux conditions suivantes: 1) Le paramètre type est utilisé uniquement comme type de retour des méthodes d'interface et non utilisé comme type d'arguments de méthode 2) Le paramètre type n'est pas utilisé comme contrainte générique pour les méthodes d'interface. " –

1

I pensez il vous manque le mot-clé out. Essayez de l'ajouter aux lignes suivantes:

public interface BInterface<out T> where T : AInterface { } 
public class Z<out T> where T : BInterface<AInterface> {} 

Je ne suis pas sûr si c'est nécessaire dans les deux endroits, cependant.

+0

Les classes ne peuvent pas être variantes, vous ne pouvez donc pas ajouter "out" ou "in" pour les paramètres génériques dans les classes. –