Changing Type during runtime

In response to my previous thread which can be read here, I've decided to create a new thread because although I mention this problem in my previous thread, this is a different subject.

To recap, I have a class Shape, which will have many inherited types. In a class Physical, I have a Property which returns a Shape object. Many classes inherit from Physical, and each inherited class will need the capability of allowing the user to change the Shape Type during runtime. I came up with a decent solution, but was wondering if anybody knows, or can think of a better way(s) to solve this:

[BrowsableAttribute(true), ReadOnly(false), TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter)),
Category("Inherited Physical Values")]

public Shapes.Shape Shape
{

get
{
if (_shape != null)
{
return _shape;
}
return DefaultShape;
}
set { _shape = value; }
}

public ShapeTypeSelection ShapeType
{

get
{
return _shapeType;
}
set
{
_shapeType = value;
ChangeShape();
}
}

private void ChangeShape()
{

switch (ShapeType)
{
case ShapeTypeSelection.ExtrudedCircle:
Shape = Activator.CreateInstance<Shapes.Extruded.ExtrudedCircle>();
break;
case ShapeTypeSelection.ExtrudedPolygon:
Shape = Activator.CreateInstance<Shapes.Extruded.ExtrudedPolygon>();
break;
case ShapeTypeSelection.ExtrudedRectangle:
Shape = Activator.CreateInstance<Shapes.Extruded.ExtrudedRectangle>();
break;
case ShapeTypeSelection.Sphere:
Shape = Activator.CreateInstance<Shapes.Sphere>();
break;
default:
break;
}
}

public enum ShapeTypeSelection
{
ExtrudedCircle,

ExtrudedPolygon,

ExtrudedRectangle,

Sphere,
}

As you can see, the solution that I have came up with involves creating an enumeration that contains a list of all the different "Types" of Shapes, obviously in String format. This poses a problem though. Everytime I create a new Shape Type Class, I have to add it to this enumeration.

I'm was thinking that an event might help, but I am not too familar with events or delegates yet. There has also got to be some sexy way of solving this using Generics that I haven't though of yet. I greaty appreciate any ideas/input:)



Answer this question

Changing Type during runtime

  • QuantumMischief

    Did I say something wrong I could really use some help with this... If I didn't explain my situation well enough, please let me know where the confusion lies. I'll explain as much as you need about my situation, because I really need an answer to this question


  • sjb31988

    I just read that link, but isn't that pretty much what I had already done The only three differences that I noticed, were:

    1) they decided to create a seperate class to do what I do in the Physical class.
    2) They pass in an index to switch between the types, whereas I create an enumeration.
    3) Their base class is an interface, while mine is an abstract class.

    Maybe I'm missing something, but I don't see how that is more efficient then what I have already done...

    Isn't there some sort of Generic Collection, which I can define as <Type> items, which also has a selected item property Something along those lines should be perfect:)


  • crp2k4

    I think I may be a little confused... I thought "design time" referred to when I am physically designing my library/forms (programming), while "runtime" was when while my application is running Am I correct in this, or are there other factors that I am missing


  • Daikoku

    I would use a shape factory to create your instances of the shapes. Hence your code would become:

    public ShapeTypeSelection ShapeType
    {
        get
        {
            return _shapeType;
        }
        set
        {
            _shapeType = value;
            Shape = ShapeCreatorfFactory.Create(_shapeType);
        }
    }

    Now the good thing about delegating creation to a factory is that you can access the factory via an interface where the concrete implementation of the factory is decided by some other type (application dependant). Thus you could have a family of shape creation factories that potentially create different families of shapes.

    The factories themselves could perhaps be initialised with what they are able to create by having them inspect a directory containing DLLs or from some configuration file. I would also deal with the concrete shape types themselves via an interface which decouples you from any form of implementation (in this case the Shape base class).

    You provide the type of shape via a strongly-typed enumeration which means everytime there is a new shape type then the enumeration needs to be updated and every type that uses the enumeration potentially requires updating too. While I am a fan of strong typing, you could replace the enum with a string and pass that to the shape factory. This would limit your updates whenever you create a new shape type to the factory only, either by updating the current factory or introducing a new one.

    Hope this has made some sense to you.


  • karen_tgha

    Yep, design time support is crucial:) Edit: I just realized that I had contridicted what I say below, I need runtime support. It's easy to change the type in the code editor, at design time.

    The Physical class, as mentioned in my first post in this thread, has a property called Shape, which gets/sets type specific properties of an object that inherits from the Shape class (ie. a rectangle has height, width, Circle has radius, Polygon has # or sides and radius, etc.).

    The Shape property can also be used to set a new object, thus changing the current type to a different Shape type. Many classes inherit this Shape property because they inherit the Physical class.

    Think of Physical the same as you would a part. Each Physical Part will have many different types of Physical Parts (Rods, Decks, Joints, Shafts, etc.), each of which can have many different types of shapes (Rods can be either an Extruded Circle, Rectangle, Polygon, etc.)

    So, what I need, is a way for my users to change the type of shape during runtime (Edit: I need this controlled through a property grid). The only solution I could think of was to create an enumeration (see first post) containing the string representations of the different types of Shapes, and then having Switch statements to switch between the different "types." I didn't find this technique to be very effiecient, because of many reasons.




  • Muhammad Akhtar Shiekh

    For the most part it makes sense to me, I just have to research a bit about what factories are.

    Is there a way to solve this problem without the use of enumerations

    EDIT: For example, isn't there something that I can use that gives me the capability of a list of all the Types of Shapes, that allows someone to select a type from a list of types


  • dron747

    Even if it isn't your best bet but I was certainly about to recommend looking into it. :)

    I didn't realize you needed design time support. Could you tell me a little more about your design and this "Physical" class and how you expect the parts of the system to interact



  • cunha

    Thanks for the example, it shed some light on using this ShapeFactory concept:)

    This raises another question though. How can I populate the listbox with types if I need all the Shape types returned from a Property in my Physical class which are going to be displayed in a dropdown listbox as a Property in a PropertyGrid

    Edit: I have tried looking into using the TypeListConverter, although I couldn't find any information on how to use it, just information that it exists. I don't know if the TypeListConverter even applies to my situation, but after reading the MSDN entry on it, it sounds like it is the solution I am looking for.


  • Pooja Katiyar

    Thanks for the link. When we started dealing with TypeConverters is kinda got beyond my area of familiarity. I tried hacking away at it for a few hours before giving up. It's good to know someone knows how to work the designer attributes/property grid. :)

  • Enes Kabacaoglu

    The following link can help you on factory patterns and it is even in C#:

    http://www.c-sharpcorner.com/Language/FactoryPatternsinCSRVS.asp


    You can convert enumerations into textual representations, e.g, :

    class EnumToString
    {
        public string GetEnumString(object enumValue)
        {
            return Enum.GetName(object.GetType(), enumValue);
        }
    }

    The user could then select from a list box populated with the string representation of the enumeration values.

    As an alternative you could have a method on the shape family factory that returns string representations of all shapes it knows how to create.


  • justin tighe

    You could:

    Interface IShapeFactory: Function Create() As Shape: End Interface

    Class ShapeFactory(Of T As {New, Shape}): Implements IShapeFactory

    Function Create() As Shape Implements IShapeFactory.Create

    Return New T()

    End Function

    Public Overrides Function ToString() As String

    Return GetType(T).Name

    End Function

    End Class

    Then populate the listbox with ShapeFactory(Of Circle), etc.

    Then when the listbox's item changes you cast the selected item to IShapeFactory, call Create, and it's all done. No need for enumerations or switch blocks. Whenever you add a new shape just add a new instance of ShapeFactory to the listbox.

    You could also not use that override of ToString and just create a ListItem with the factory instance as the value and specify the display text yourself.

    Much luck!



  • DSent

    FYI, the answer to this question can be found at a previous thread of mine:

    http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=602792&SiteID=1&mode=1




  • Changing Type during runtime