views:

176

answers:

5

I have a List<T> and I need to avoid the behavior I'm about to outline:

    // assume cls and numberToAdd are parameters passed in.
    int pos = numberToAdd;
    List<MyClass> objs = new List<MyClass>(numberToAdd);

    for(int i = 0; i < numberToAdd; i++)
    {
        objs.Add(cls);
        objs[i].X = -((pos * cls.Width) + cls.Width / 2);
        pos--;
    }

    Console.WriteLine(objs[0].X + "\r\n" + objs[1].X);

This results in this writeline printing the same value.

Basically what I need is to change the behavior of the "Add" method. I'd like to add a new instance of the object with the same values and not simply a reference to the same object. I understand this will use alot more memory.

+1  A: 

What is the 'cls' variable? Just create a new one inside each loop. What you want to do is clone it; but honestly that'll be confusing. I'd suggest just creating a new one per loop.

-- Edit

Noticed you'd comment about 'cls'.

I suggest you clone it then (assuming you can't change the call and do my above suggestion). Do this by just creating a new one, and copying all the properties over.

Typically, if you have control of the Type of 'cls', you just make a 'Copy' constructor. It's like so:

class Foo {
    private int x;

    public Foo (Foo toCopy) {
       this.x = toCopy.x;
    }

    ...
}
Noon Silk
Ended up doing this, but in a method instead of the constructor -- is there an advantage to one or the other?
Nate Bross
Not really; it's okay either way. The constructor will guarantee that you have a fully cloned object before you can do anything with it. The method may mean you're object is empty beforehand, until you call '.Clone()' but that's fine too.
Noon Silk
+1  A: 

Might want to extend cls to include a clone method. Extension method would work if you can't modify the cls class.

then change objs.Add(cls); to objs.Add(cls.Clone());

Rob
A: 

Ah. You need to implement cls as a struct so that it exhibits pass by value semantics.

OR you need to implement a clone method on your cls object so that you can create a method to clone the object and thus create a new reference to it so that you can do this.

Even if you don't have access to the object itself you may be able to create an extension method to do this.

public cls Clone(this cls)
{
    //initialise the object to clone it.
    return new cls(this.param1, this.param2,...) 
}
Spence
A: 

Looks like the same object, cls is getting added numberToAdd times to the list.

You need to create a new instance of your objects inside the loop.

for(int i = 0; i < numberToAdd; i++)
{
    MyClass c=new MyClass(...);
    c.X = -((pos * c.Width) + c.Width / 2);
    objs.Add(c);
    pos--;
}
spender
A: 

Have MyClass Implement ICloneable and then simply use

objs.Add((MyClass)cls.Clone());
Simon Fox
I think ICloneable.Clone() returns an object, so you'll need a cast before you can add the object to the List.
Badaro
done, thanks :)
Simon Fox