Jump to content
  • Advertisement
Sign in to follow this  
deadlydog

"Dynamic" memory allocation in C#?

This topic is 3652 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

Is it possible to declare an array of class objects without knowing the class type beforehand? For example, in my particle system class I declare an array of objects for my particles: Object[] cParticles; Now, in my initialization function I would like to pass in the class type to use for the particles, so something like: public void InitializeParticleSystem(Object cParticleInstance, int iNum) { cParticles = new typeof(cParticleInstance)[iNum]; } However, this gives me a compile-time error saying it is expecting a type (instead of the typeof function). I have also tried: public void InitializeParticleSystem(Object cParticleInstance, int iNum) { Type cParticleType = typeof(cParticleInstance); cParticles = new cParticleType[iNum]; } but this also gives me a compile-time error. Basically I want my particle system to be able to handle different types of particles (i.e. different particle classes), but the class type to use will not be known until run-time. Is there a way to do this that anybody knows of? Any ideas/comments are appreciated. Thanks.

Share this post


Link to post
Share on other sites
Advertisement
I think you're stuck with just initialising an array of object and then casting the object on retrieval using a nice big switch statement.

To me it sounds like your design is backwards if you don't know the type at run time. Can you instead make a ParticleBase class or perhaps use interfaces to support the functions you need in the particle system?

edit: better still, you should be using data to differentiate the particle types, not classes, unless the behaviour of each particle type is wildly different, in which case interfaces would be the better solution I feel.

Share this post


Link to post
Share on other sites
Quote:
Original post by BLiTZWiNG
To me it sounds like your design is backwards if you don't know the type at run time. Can you instead make a ParticleBase class or perhaps use interfaces to support the functions you need in the particle system?


I was using a ParticleBase class when I ran into this problem. The problem occurs because I declare an array or ParticleBase objects for the array, so I had:

public void InitializeParticleSystem(int iNum)
{
cParticles = new ParticleBase[iNum];
}

The problem is that if the class that inherits from ParticleBase, I'll call it ParticleChild, declares any new data such as a float or int or whatever, cParticles will not have allocated memory for that extra data, since it just declared an array of ParticleBase objects, not ParticleChild objects. I thought about this after I was getting a run-time error about not being able to convert a ParticleBase object to a ParticleChild object.

Quote:
Original post by BLiTZWiNG
better still, you should be using data to differentiate the particle types, not classes, unless the behaviour of each particle type is wildly different

Yes, the particle classes will have very different behaviors. For example, some particle types movement might be based on velocity and acceleration vectors, and other might be based on temperature or mass.

Thanks for the suggestions though. I'll look into interfaces, as I've heard about them but haven't investigated them much. In the mean time, any other suggestions would be very appreciated. Thanks.

Share this post


Link to post
Share on other sites
Deadlydog,

While I agree with BLiTZWiNG (You might want to consider your design), I don't know the full details of what you're attempting, so I wont judge you.

It is possible to do what you want by using Generics. Try this:


public T[] InitializeParticleSystem<T>(int iNum) where T : new()
{
T[] particles = new T[iNum];
for( int i = 0; i < iNum; i++ )
particles = new T();

return particles;
}



Note: The above will only work with reference types which have a default constructor. If you need it work with value types, remove the Generic Constraint, and remove the iterated constructor.

Cheers!

Share this post


Link to post
Share on other sites
deadlydog,

After reading over your second post, it's important that you understand that when using array allocation you must not only allocate the array, but also the individual objects within the array. This is the curse (and benefit) of reference types.

For example...


// This line allocates an array of 10 objects, however, those 10 objects
// can be anything that derives from object (all reference types)
Object[] objects = new Object[10];




However, because Object is a reference type, I must still allocate the individual elements of the array.


// This allocates MyBaseType, and stores it in index 0 of the array
objects[0] = new MyBaseType();




As you can see, I've still constructed an instance of MyBaseType, including all members, fields, etc...which is contained iwhtin MyBaseType, but not Object.

In this event, I can now reference this object as objects[0]. This is where interfaces and polymorphism becomes important. Because while I can store in the array any type which derives from the base type, I can only access the interface of the base class. However, it'll use the implementation of the derived class.

Anyways, I highly recommend you look into interfaces and polymorphism. You shouldn't and likely dont want to use Generics for this. Though the method I showed you will work as indicated.

Cheers!

Share this post


Link to post
Share on other sites
Quote:

To me it sounds like your design is backwards if you don't know the type at run time.


There's absolutely nothing inherently wrong with a design that needs the types to be known only in run-time. Especially in games. For example, you may need one type of particle when event A happens, and a much different one if event B happens. It's much more elegant to associate types with events than implement a big switch algorithm. Sure, it's much better if you have only one class and express all the differences with data variation, but sometimes the differences are so significant that you can't do that, and this might be one of those times. It's up to the OP to judge that.

Anyway, although I'm not exactly sure how you're trying to do things, there's System.Activator() which can create an instance if you pass it a System.Type. Or, as an alternative, you could support the ICloneable interface. In any case the static type of the array must be known at compile-time(and it will probably be a parent Particle class), but the actual dynamic types of particles can be handled at run time.

Btw, typeof() gets typenames as arguments only. If you want to get the System.Type of an instance, use instance.GetType() method instead.

Share this post


Link to post
Share on other sites
Quote:
Original post by JWalsh
After reading over your second post, it's important that you understand that when using array allocation you must not only allocate the array, but also the individual objects within the array.

Yes, I realize that. I just didn't put it in to keep my example simple. Thanks though.

After looking into interfaces, it looks like they aren't what I'm looking for. In my base class I will be declaring several floats and implementing a few methods, which isn't allowed in an interface. I could have the class that inherits the interface implement the methods, but it seems kinda pointless to have say 4 classes that implement the interface, implement the methods all the exact same way; that is why I wanted to use inheritance, so the inheriting classes wouldn't need to implement the common functions.

Generics may be the way to go I think. I used templates in C++ so I assume generics are similar. I'll have to look into them too though and make sure they can do the job. Thanks for all of the advise so far! This is why I love GameDev!!

P.S. On a side note, has anybody else noticed GameDev's site being down spuratically the past few days. It seems to be down for 5 - 10 minutes at a time about a quarter of the time I try to go to it. Oh well :)

Share this post


Link to post
Share on other sites
The following will work fine. Note that the array is of type Base[], but each element can be of type Base (assuming it is not abstract) or any of its derived types.


class Base
{
...
};

class Derived1 : Base
{
...
};

class Derived2 : Base
{
...
};

Base[] bar = new Base[2];

bar[0] = new Derived1();
bar[1] = new Derived2();




Edit: And you're free to implement the common functionality and data in the Base class. When you think about it, any code that's going to access this array is going to only be able to access members that are common to all of the particle types. Thus, you extract these common members into a parent class.

Share this post


Link to post
Share on other sites
Quote:
Original post by mikeman
Quote:

To me it sounds like your design is backwards if you don't know the type at run time.


There's absolutely nothing inherently wrong with a design that needs the types to be known only in run-time. Especially in games. For example, you may need one type of particle when event A happens, and a much different one if event B happens. It's much more elegant to associate types with events than implement a big switch algorithm. Sure, it's much better if you have only one class and express all the differences with data variation, but sometimes the differences are so significant that you can't do that, and this might be one of those times. It's up to the OP to judge that.



I didn't mean to imply that his design was "wrong" as such. Given that he said he was making a particle system, not knowing the type at design time seems uncommon of a particle system to me.

Quote:
deadlydog
After looking into interfaces, it looks like they aren't what I'm looking for. In my base class I will be declaring several floats and implementing a few methods, which isn't allowed in an interface. I could have the class that inherits the interface implement the methods, but it seems kinda pointless to have say 4 classes that implement the interface, implement the methods all the exact same way; that is why I wanted to use inheritance, so the inheriting classes wouldn't need to implement the common functions.



You don't implement the method in the interface, you "inherit" from one in your new class. That way you're guaranteed that the class has the method say "update()" but the implementation is left to the class that inherits from the interface. So you don't care what happens in update(), all you care about is that every IParticle has an update() method and knows how to update itself. That also means that it doesn't matter what type is stored in the list as long as it supports IParticle, so you could make a generic List<IParticle> and know that every different particle, no matter how it works, provides a method named "update".

Going by what you're saying, the methods will be doing the same thing, so I don't quite see how your functions could be the same if they need to do wildly different things with different data... or maybe you need to make your data names more generic (like say, ActivationThreshold instead of MaxTemperature) so that you can reuse the same variable names and then use an enum to switch the type of particle.

HTH.

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!