views:

21

answers:

2

Maybe I just don't know what to search for, but I'm going a little bonkers here trying to figure out how to create a collection of inherited classes. The base class, I will never use.

Basically, I have 3 components:

  1. A base class call ImageFormat
  2. Child classes of ImageForm
  3. Code in Sub Main() to loop create a collection and loop through it.

So it does it, #3. The problem is that it always gets the last item added to the collection and uses it's values only.

Here's my Base Class:

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

And here are the child classes:

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

(don't know if these child classes need to different, like just instantied from ImageFormat type or Singleton patterns - would appreciate anything thoughts you have on this)

Then, my routine is:

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

This returns Windows Enhanced Metafile three times at the Console. What am I doing wrong here?

+1  A: 

Well, your _name et al are Shared, which means they are class-level variables. When you're adding WindowsEnhancedMetafile, it happens to overwrite these fields with WMF-specific information. If you changed your code to:

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

you would've had "Windows Bitmap" printed three times.

All you have to do is to change your field declarations to

Protected _extentions As  String()
Protected _targettype As String
Protected _name As String
Anton Gogolev
excellent, thank you anton. great explanation. michael got in first, but +1 for you as well.
Otaku
+2  A: 

The three properties:

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

Are marked as Shared - they belong to the class not the object.

Each time you assign a new value to _name it overrides the old value, thus why you get the same name printed each time.

It should be:

Protected _extentions As String()
Protected _targettype As String
Protected _name As String
Michael Shimmins
perfect! thank you!
Otaku