[C#] Creating new instances using Polymorphism

Started by
11 comments, last by ChaosEngine 14 years, 10 months ago
I have a class that inherits from another class, in this case Bullet is the base class and PistolAmmoNormal is the class that inherits from Bullet. Is it possible to pass base type Bullet into a class and then create a new instance based on what type of Bullet was passed in? For example:

// Current type of bullet is PistolAmmoNormal
PistolAmmoNormal bullet_Current;
// Generate all possible instances for that type
bullet_CurrentList = bullet_Manager.GenerateAllBullets(bullet_Current);


        public List<Bullet> GenerateAllBullets(Bullet bullet_Current)
        {
            bullet_Current = new WhatEverTheTypeOfBulletBeingPassedInIs(); 

.....
I hope that made sense. Thank you guys.
Advertisement
I'm not really sure what you're trying to achieve here. If you want a method that creates a List<> of Base, you could use a generic function like this

List<Bullet> GenerateAllBullets<BulletSubType>(int numBullets)   // generic constraint: BulletSubType must derive from Bullet and have a default constructor   where BulletSubType : Bullet, new(){    List<Bullet> bulletList = new List<Bullet>();    for (int i = 0; i < numBullets; ++i)    {        bulletList.Add(new BulletSubType());    }}


If you provide more detail as to what you actually want, we might be able to help more.
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
You can use reflection to do what you want.

using System;using System.Reflection;namespace CSharpTest{    class Base    {        public readonly string type;        public readonly string name;        protected Base(string type, string name)        { this.type = type; this.name = name; }    }    class DerivedA : Base    {        public DerivedA(string name)            : base("A", name)        {}    }    class DerivedB : Base    {        public DerivedB(string name)            : base("B", name)        {}    }    static class Program    {        static Base createOfType(Base obj)        {            Type passedType = obj.GetType();            Type stringType = "".GetType();            Type[] parameterTypes = { stringType };            ConstructorInfo ci =  passedType.GetConstructor(parameterTypes);            object[] parameters = { "Bar" };            return (Base)ci.Invoke(parameters);        }        static void Main(string[] args)        {            DerivedA obj = new DerivedA("Foo");            Base newObj = createOfType(obj);            Console.WriteLine(newObj.type);            Console.WriteLine(newObj.name);        }    }}


But there is probably a better design that avoids needing to do this.
[TheUnbeliever]
Sorry guys.

What I would like is to create a new instance of PistolAmmoNormal inside the GenerateAllBullets. Exactly the same as:

bullet_Current = new PistolAmmoNormal(); 


However, I want to pass the in bullet_Current as type Bullet. The type of Bullet in this case PistolAmmoNormal would create a new PistolAmmoNormal, if the type of bullet was PistolAmmoFlammable then a new instance of PistolAmmoFlammable would be created.

bullet_Current = new PistolAmmoFlammable(); 


I was wondering if there was a good way of doing this automatically depending on type?!
Quote:Original post by TheUnbeliever
You can use reflection to do what you want.

*** Source Snippet Removed ***

But there is probably a better design that avoids needing to do this.


Why would you use reflection? What's wrong with either a generic approach or a polymorphic Create method?

i.e
public class Bullet{    abstract Bullet Create();}public class PistolAmmoNormal{    Bullet Create()    {        return new PistolAmmoNormal();    }}


if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
Quote:Original post by Spa8nky
I was wondering if there was a good way of doing this automatically depending on type?!


This is what my code does. Copy and paste it, and try switching the type of 'obj' in Main from DerivedA to DerivedB.
[TheUnbeliever]
Quote:Original post by ChaosEngine
Why would you use reflection? What's wrong with either a generic approach or a polymorphic Create method?


Er, because I'm an idiot.
[TheUnbeliever]
Quote:Original post by TheUnbeliever
Quote:Original post by ChaosEngine
Why would you use reflection? What's wrong with either a generic approach or a polymorphic Create method?


Er, because I'm an idiot.


Lol, I wouldn't say that at all. Your solution will certainly work and is probably the most flexible approach. There might be an easier way, that's all.

To the OP, can you post a complete example of what you want. Don't just post 1 or 2 lines, show the entire function and an example of calling it.

Why do you want to pass in an instance of the type?

You've been given 3 solutions already, do any of them fit?

You could also do
Bullet CreateBulletOfSameType<BulletSubType>(BulletSubType bullet)   where BulletSubType : Bullet, new(){    return new BulletSubType();}


this will work if you have
PistolAmmoNormal bullet = null;Bullet bulletCurrent = CreateBulletOfSameType(bullet);// bulletCurrent is a PistolAmmoNormal 


but not
Bullet bullet = new PistolAmmoNormal;Bullet bulletCurrent = CreateBulletOfSameType(bullet);// bulletCurrent is a Bullet 

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight
Of course, that makes sense now.

ChaosEngine's method is precisely what I am after.

However why would I use abstract instead of virtual and override, is it a faster way of implementing the same thing?

E.G.

 public class Bullet{    public virtual Bullet Create();}public class PistolAmmoNormal{    public override Bullet Create()    {        return new PistolAmmoNormal();    }}
Quote:Original post by Spa8nky
Of course, that makes sense now.

ChaosEngine's method is precisely what I am after.

However why would I use abstract instead of virtual and override, is it a faster way of implementing the same thing?


It's nothing to do with speed. If you have a virtual method you have to provide an implementation of it. If Bullet is a valid concrete class in your code, then use virtual i.e.

public class Bullet{   public virtual Bullet Create()   {       return new Bullet();   }}


However if every type of bullet must be a sub-class then use abstract.


if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

This topic is closed to new replies.

Advertisement