2012-03-08 4 views
0

Pour le problème que j'ai ces classes:VB Generics « ne peut pas être converti »

Public MustInherit Class BaseLeaf(Of T) 
    Implements IBaseLeaf 
    // etc 

Public Class WebsiteLeaf 
    Inherits BaseLeaf(Of Headline) 
    // etc 

Public Class WebsiteCollection 
    Inherits BaseCollection(Of WebsiteLeaf) 
    // etc 

Public Class SubscriptionList 
Private mCollection As BaseCollection(Of IBaseLeaf) 

Public Sub LoadSubscriptions(ByVal collection As BaseCollection(Of IBaseLeaf)) 
    mCollection = collection 
End Sub 

dans la classe principale, je suis en train d'appeler la fonction suivante:

Private Sub FetchSubscriptions(ByVal websites As WebsiteCollection) 
     gUser.SubscriptionList.LoadSubscriptions(websites) 
     // code 
End Sub 

Cela accès LoadSubscriptions avec passer la variable "sites Web". Comme vous pouvez le voir LoadSubscriptions s'attend à une BaseCollection (Of IBaseLeaf).

La variable "websites" est un objet WebsiteCollection, qui est un objet BaseCollection (Of WebsiteLeaf (Of Headline)).

Maintenant j'obtiens l'erreur: La valeur du type 'WebsiteCollection' ne peut pas être convertie en 'BaseCollection (Of IBaseLeaf)'.

Qu'est-ce que je fais mal ici?

+0

Vous aimeriez en savoir plus sur [covariance et contravariance dans les génériques] (http://msdn.microsoft.com/en-us/library/dd799517.aspx) – MarkJ

Répondre

2

Si la classe B est un descendant de la classe A cela ne signifie pas que Collection(Of B) est un descendant de Collection(Of A)!

Si vous avez ces définitions

Dim stringList As List(Of String) 

Public Sub DoSomthingWithList(list As List(Of object)) 
    list.Add(Date.Now) 
End Sub 

et vous pouvez appeler la méthode comme celui-ci

DoSomthingWithList(stringList) 

alors la méthode essaierait d'ajouter un Date à la liste qui est en fait une liste de chaînes ! Comme le paramètre est tapé object, la date sera encadrée (c'est-à-dire convertie en objet) mais pas convertie en chaîne.

Par conséquent, les collections List(Of X) et List(Of Y) ne sont jamais compatibles, même si Y hérite de X.


Let look à un autre exemple

Public Class TestClass 
    Implements IBaseLeaf  
    // etc 

Qu'est-ce qui se passe si vous appelez LoadSubscriptions avec un WebsiteCollection?

Public Sub LoadSubscriptions(ByVal collection As BaseCollection(Of IBaseLeaf))  
    collection.Add(New TestClass()) 
End Sub  
Questions connexes