2010-05-12 5 views
1

Peut-être que je ne sais pas quoi chercher, mais je vais un peu de bon sang ici en essayant de comprendre comment créer une collection de classes héritées. La classe de base, je ne l'utiliserai jamais.Impossible de créer une collection de classes héritées

Fondamentalement, j'ai 3 composants:

  1. un appel de classe de base ImageFormat
  2. classes d'enfant de Imageform
  3. code dans Sub Main() à boucle créer une collection et boucle à travers elle.

Ainsi, il le fait, # 3. Le problème est qu'il obtient toujours le dernier élément ajouté à la collection et utilise uniquement ses valeurs.

Voici mon classe de base:

Public MustInherit Class ImageFormat 
    Protected Shared _extentions As String() 
    Protected Shared _targettype As String 
    Protected Shared _name As String 

    Public ReadOnly Property Extentions As String() 
     Get 
      Return _extentions 
     End Get 
    End Property 
    Public ReadOnly Property TargetType As String 
     Get 
      Return _targettype 
     End Get 
    End Property 
    Public ReadOnly Property Name As String 
     Get 
      Return _name 
     End Get 
    End Property 
End Class 

Et voici les classes d'enfants:

Class WindowsEnhancedMetafile 
    Inherits ImageFormat 
    Sub New() 
     _extentions = {"EMF"} 
     _targettype = "jpg" 
     _name = "Windows Enhanced Metafile" 
    End Sub 
End Class 
Class WindowsBitmap 
    Inherits ImageFormat 
    Sub New() 
     _extentions = {"BMP", "DIB", "RLE", "BMZ"} 
     _targettype = "jpg" 
     _name = "Windows Bitmap" 
    End Sub 
End Class 
Class WindowsMetafile 
    Inherits ImageFormat 
    Sub New() 
     _extentions = {"WMF"} 
     _targettype = "jpg" 
     _name = "Windows Metafile" 
    End Sub 
End Class 

(ne sais pas si ces classes d'enfants doivent différents, comme tout instantied de type ImageFormat ou Modèles Singleton - apprécierait tout ce que vous avez des pensées à ce sujet)

Ensuite, ma routine est:

Sub Main() 
    Dim imgFormats As New List(Of ImageFormat) 
    imgFormats.Add(New WindowsBitmap) 
    imgFormats.Add(New WindowsMetafile) 
    imgFormats.Add(New WindowsEnhancedMetafile) 
    Dim name As String = String.Empty 
    For Each imgFormat In imgFormats 
     name = imgFormat.Name 
     Console.WriteLine(name) 
    Next 
    Console.ReadLine() 
End Sub 

Ceci renvoie Métafichier Windows amélioré trois fois sur la console. Qu'est-ce que je fais mal ici?

Répondre

2

Les trois propriétés:

Protected Shared _extentions As String() 
Protected Shared _targettype As String 
Protected Shared _name As String 

sont marqués comme étant partagée - ils appartiennent à la classe pas l'objet.

Chaque fois que vous attribuez une nouvelle valeur à _name, elle remplace l'ancienne valeur, ce qui explique pourquoi vous obtenez le même nom imprimé à chaque fois.

Il devrait être:

Protected _extentions As String() 
Protected _targettype As String 
Protected _name As String 
+0

parfait! Je vous remercie! –

1

Eh bien, vos _name et autres sont Shared, ce qui signifie qu'ils sont des variables de niveau classe. Lorsque vous ajoutez WindowsEnhancedMetafile, il arrive d'écraser ces champs avec des informations spécifiques à WMF. Si vous avez changé votre code à:

imgFormats.Add(New WindowsMetafile) 
imgFormats.Add(New WindowsEnhancedMetafile) 
imgFormats.Add(New WindowsBitmap) 

vous auriez fait imprimer "Windows Bitmap" trois fois.

Tout ce que vous avez à faire est de changer vos déclarations sur le terrain à

Protected _extentions As String() 
Protected _targettype As String 
Protected _name As String 
+0

excellent, merci Antón. bonne explication. Michael est entré en premier, mais +1 pour vous aussi. –

Questions connexes