Nate
Nate

Reputation: 30636

.NET Generic List<T> Problem, works by design, need work around. Add value instead of reference

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.

Upvotes: 2

Views: 618

Answers (5)

Simon Fox
Simon Fox

Reputation: 10561

Have MyClass Implement ICloneable and then simply use

objs.Add((MyClass)cls.Clone());

Upvotes: 0

spender
spender

Reputation: 120480

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--;
}

Upvotes: 0

Spence
Spence

Reputation: 29332

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,...) 
}

Upvotes: 1

Rob
Rob

Reputation: 1328

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());

Upvotes: 1

Noon Silk
Noon Silk

Reputation: 55082

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;
    }

    ...
}

Upvotes: 1

Related Questions