2010-11-24 5 views
3

Je suis en train de faire ce qui suit et à défaut:résolution polymorphes des paramètres génériques dans l'unité registerType

class base {} 

class derived1 : base {} 

class derived2 : base {} 

interface itr<t> 
where t : class, base 
{} 

class c1: itr<derived1> 
{} 

class c2 : itr<derived2> 
{} 

// Les 2 inscriptions suivantes échouent:

_unityContainer.RegisterType<itr<base>, c1>("c1"); 

_unityContainer.RegisterType<itr<base>, c2>("c2"); 

L'erreur que je reçois est que le le deuxième paramètre dans les enregistrements ci-dessus ne peut pas être classé dans le premier paramètre et cet enregistrement n'est pas valide. Des suggestions sur comment je peux faire cela?
Je dois faire ce qui précède au lieu de m'enregistrer avec les classes derived1 ou derived2 en tant que paramètres génériques car pendant la résolution, je ne veux pas connaître le type dérivé exact que je suis en train de résoudre. Je veux seulement travailler avec des méthodes de type de base polymorphiquement.

Répondre

5

Vous ne pouvez pas faire cela parce que les génériques ne sont pas covariants. C'est-à-dire que le type itr<derived1> ne peut pas être converti en itr<base>, même si derived1 peut être converti en base.

Voici un exemple des raisons pour lesquelles, en utilisant le cadre List<T> classe:

List<string> list1 = new List<string>(); 
list1.Add("Hello, World!"); 

// This cast will fail, because the following line would then be legal: 
List<object> list2 = (List<object>)list1; 

// ints are objects, but they are not strings! 
list2.Add(1); 

accès Alors list1[1] renverrait une boîte int dans une liste qui a été déclarée pour contenir string s. Par conséquent, cette distribution n'est pas autorisée car elle casserait le système de type. Par conséquent, cette distribution n'est pas autorisée.

(Comme une note de côté, dans la clause where t : class, base, vous n'avez pas besoin de spécifier class. base lui-même est un type de référence, de sorte que la contrainte class est redondante.)

Questions connexes