tags:

views:

99

answers:

3

I have a Base Class, called primitive Graphics. derived from this class are several different types of graphics, squares, rectangles, lines, etc.

I am storing those graphics in an object that inherits collectionbase. This causes a problem because I cannot access any of the members in the derived class when they are added to the collection. Here is the default property for my primitivecollection class

Public Class PrimitiveCollection
    Inherits CollectionBase
    ''' <summary> 
    ''' Get or set a primitive object by index 
    ''' </summary> 
    Default Public Property Item(ByVal index As Integer) As Primitive
        Get
            Return DirectCast(List(index), Primitive)
        End Get
        Set(ByVal value As Primitive)
            List(index) = value
        End Set
    End Property

My current workaround is to just put all of the public members in the base class, however this is starting to look ugly as I add more derived classes that need members available to the derived class only

A: 

You will need to cast the instances in the collection to the derived type in order to access their specific members.

I will add an example:

PrimitiveCollection primitives = GetPrimitives() ' this gets a mixture of types
If GetType(PrimitiveRectangle) = primitives[0].GetType() Then
    ' this is a PrimitiveRectangle object
    PrimitiveRectangle rect = CType(primitives[0], PrimitiveRectangle)
    ' now you can access specialized members through rect
End If

I didn't use VB.NET in a couple of years, so there may be issues with the syntax...

Fredrik Mörk
+1  A: 

Your question is about inheritance and interfaces. The following is my opinion

Each Primitive should implement an interface, IPrimitive. Every Primitive in the Collection implements IPrimitive and the only things in IPrimitive are the things that apply to all types of IPrimitives. For example: Draw()

So when working with your collection, you have a collection of drawable objects. If you intend to work with a collection as a collection of just Rectangles, you should use a List<Rectangle> rather than a collection of Primitives.

Putting more properties onto the base class (or IPrimitive) is a bad idea, because they won't make sense for all objects. Width could work for a Rectangle, but gets shady when you're working with a Trapezoid or Triangle. Instead the Commonality should be as little as is necessary to work with the objects as a collection. And when you need to work with the objects as their derived classes, you should be referencing them without using the collection.

Tom Ritter
+1  A: 

If you're storing multiple types of object within a single collection, then you'll need to cast between them to access type-specific members, yes.

If you're actually storing multiple objects of a single derived type in a collection, you should look at using generics instead, so that the collection remains strongly typed (i.e. the compiler knows that the collection only contains instances of the derived type).

Jon Skeet