[C#] Making a copy of a class to add a unique instance to a list?

Started by
7 comments, last by Spa8nky 14 years, 5 months ago
Hi folks, I am currently playing around with lists and I realize that if I want to add a unique instance of a class to a list then I must create a new instance of that class. However, is there a way to create a clone or new instance to add to the list when adding? Here is my code:

            Contact contact = new Contact();
            List<Contact> list_Contact = new List<Contact>();
            
            // ====[AABB/Triangle Collision]======
            int triangles_Intersected = 0;
            for (int i = 0; i < Game1.debug_Triangle.Length; i++)
            {
                if (aABB.Intersects(Game1.debug_Triangle, ref contact))
                {
                    triangles_Intersected++;
                    list_Contact.Add(contact);
                }
            }

The line list_Contact.Add(contact) will only ever add the same instance of contact each time to a new element in the list. Is there a way to clone or copy the current contact class so that it makes a new, separate instance to be addded to the class? Thank you.
Advertisement
There certainly is no standard way to do this. Three solutions that come up in my mind:

  • Make your own list class, which clones objects at insertion, something like CloningList<T> where T : ICloneable.

  • Make Contact a value type.

  • Make Contact immutable.
Try this:
            List<Contact> list_Contact = new List<Contact>();                        // ====[AABB/Triangle Collision]======            int triangles_Intersected = 0;            for (int i = 0; i < Game1.debug_Triangle.Length; i++)            {                Contact contact = new Contact();                if (aABB.Intersects(Game1.debug_Triangle, ref contact))                {                    triangles_Intersected++;                    list_Contact.Add(contact);                }            }

Depending on the complexity of the game, this might not be acceptable for performance. Consider making contact a value type if possible. But try the simplest approach before the more complex ones.
Thanks for the quick answers both of you.

I have tried the moving the creation of a new Contact like rip-off suggested before. Unfortunately, I wan't sure just how sensible it was to be generating lots of new instances each frame?

I figured that creating just one instance at load time and then cloning that instance when copying to a list would be the faster way, but I am not experienced enough in this area to know for certain if this is true.

Which one of Sam's options would others suggest if creating lots new instances each frame just isn't feasible?
Cloning when you add to the list would be creating new objects every frame. Cloning is just a special kind of creation.
Is contact your own type? Can we see it? Making it a "struct" rather than a class is probably the best thing you can do.
Quote:Original post by rip-off
Is contact your own type? Can we see it?


Yes to both.

    public class Contact    {        public Vector3 location;                // Location of the contact (always a point on the triangle) [World Coordinates]        public Vector3 normal;                  // Contact normal        public float penetration;               // Penetration depth                    // Non stationary contact variables        public float time_First;                // Time of first collision contact        public float time_Last;                 // Time of last collision contact        static float max = float.MaxValue;        static float min = float.MinValue;        public static bool KeepClosest(float value)        {            if (value < max)            {                max = value;                return true;            }            else            {                return false;            }        }        public static bool KeepFurthest(float value)        {            if (value > min)            {                min = value;                return true;            }            else            {                return false;            }        }    }


I've had a thought....

What if I have a limit to the number of possible contacts and create a pool of all possible contacts during load time? Then, instead of creating a new contact each frame I can just get a valid contact from a pool.

Will this be a better, faster option or is my idea horribly flawed?

Changing the keyword "class" to "struct" would probably be an better option. Structs are value types, cheap to instantiate and copy. Not unlike a primitive. This is what we've been suggesting all along.
Quote:
Changing the keyword "class" to "struct" would probably be an better option. Structs are value types, cheap to instantiate and copy. Not unlike a primitive. This is what we've been suggesting all along.


Point taken, thank you for the help. My class is now a struct.

This topic is closed to new replies.

Advertisement