Jump to content
  • Advertisement
Sign in to follow this  
Spa8nky

[C#] Creating new instances using Polymorphism

This topic is 3314 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?!

Share this post


Link to post
Share on other sites
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();
}
}


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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();
}
}

Share this post


Link to post
Share on other sites
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.


Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!