-1

can some one explain to me how to break the chain with a NEW statement?

Let me clarify the chain I’m talking about. When I call to a class I use the NEW statement like so

Myclass x =new Myclass();

My understanding is this creates a new empty instance of Myclass. Now correct me if I’m wrong but having a new empty instance one should be able to add what ever data the class supports?

I use this lot and would think the above to be true until adding data in such a manner

Myclass x =new Myclass();

//oldMyclass being old data that needs to be changed then 
//added back to the class as a new or duplicate entry  
x = oldMyclass[1]; 
//we change the data 
x.red= 0x54;
//we add it back 
oldMyclass.add(x); 

All is good until we edit the data after adding it say we need to change another value. We access the oldMyclass and select the proper item say its index is 2 but we only want to change the values of index 2

Myclass x =new Myclass();
x = oldMyclass[2]; 
x.red=soemvalue;
oldMyclass[2] = x; 

This will change the red value of both index 1 and index 2. How can I break the chain between index 1 and index 2?

I think I might have over simplified this question let me know.

Thanks for any information.

Edit: Here is the copy method that I tried

public static Items.SavedItem Copy(Items.SavedItem old)
        {
            Items.SavedItem x = new Items.SavedItem();
            x.generator = old.generator;
            x.hireling_class = old.hireling_class;
            x.id = old.id;
            x.item_slot = old.item_slot;
            x.owner_entity_id = old.owner_entity_id;
            x.socket_id = old.socket_id;
            x.square_index = old.square_index;
            x.used_socket_count = old.used_socket_count;
            return x;
        }
CKY
  • 45
  • 8
  • I don't see any `List` here. What are you asking? – Matt Burland Mar 05 '14 at 17:56
  • assume oldMyclass is a list – CKY Mar 05 '14 at 17:58
  • I think the concept you are looking for is a `clone`. Maybe have a look here: http://stackoverflow.com/questions/78536/deep-cloning-objects-in-c-sharp – Iain Ballard Mar 05 '14 at 17:58
  • 3
    Your question is currently pretty unclear. It would be a lot simpler if you'd show a short but *complete* example which demonstrates the problem. – Jon Skeet Mar 05 '14 at 17:58
  • 1
    If `oldMyClass` is in fact `List`, then what you've done (at some point) is add the same item twice. That's the only reason you'd have the problem you are describing. There is no "link" between index 1 and index 2 unless they happen to both be the same object. Also, you don't need `new MyClass()` if you are just going to assign from your List. You should spend some time understanding how reference types work. – Matt Burland Mar 05 '14 at 18:01
  • I tried clone and the issue still stands the fact that you add a new item to the class links it to the the existing item – CKY Mar 05 '14 at 18:02
  • @MattBurland if you look @ the fist code block I make the oldMyclass[1] to the new Myclass object make an edit then add it back as what I thought would be a new list item using oldMyclass.add(x); but apparently the 2 becomne linknd how can I unlink them – CKY Mar 05 '14 at 18:08
  • @CKY: No. You assigned the reference at `oldMyclass[1]` to a variable called `x`. You didn't remove it from the original list and, although you did create a new one, you immediately overwrote the reference with the reference from your collection. You then just added *the same object* back into the list (`List` does not stop you from adding duplicates, some collection types do). That's why `oldMyClass[2]` and `oldMyClass[1]` are the *same object* – Matt Burland Mar 05 '14 at 18:13
  • yes so how do I break the chain – CKY Mar 05 '14 at 18:16

1 Answers1

1

So let's say, for arguments sake, you have a class like this:

public MyClass
{
    public string Foo { get; set; }
}

And you have a collection

List<MyClass> myList = new List<MyClass>();

Now you create an instance of MyClass

MyClass obj1 = new MyClass() { Foo = "bar" };

Now if you do this:

myList.Add(obj1);
myList.Add(obj1);

You now have a list with TWO members, but they happen to be the same object. Whats stored in the list is a reference to the object you added, not the object itself. So myList[0] == myList[1]

Now if you did this:

MyClass item = myList[1];

And then:

item.Foo = "something else";

Both the item at index 1 and the item at index 0 will have 'Foo == "something else"' because they are the same item.

Another point that seems to be confusing you is this: myList has two items. If I do this:

MyClass item = myList[0];

myList still has two items. Indexing a collection doesn't remove it and because of that, there is no need to add the item back to the list. It's already there. All I've done is copy the reference from myList to a variable named item.

There are collections (Stack and Queue for example) that do work on the principle that you will remove items and (potentially) add them back, but List doesn't work that way.

So if you wanted to add multiple objects to myList you need to create multiple objects with the new keyword. For example:

List<MyClass> myList = new List<MyClass>();
MyClass obj1 = new MyClass() { Foo = "bar" };
myList.Add(obj1);
obj1 = new MyClass() { Foo = "something else" };    // Note: I've reused the variable, but this is a *new* object
myList.Add(obj1);

Or, if you don't need the new object assigned to a variable, you can simply if to:

List<MyClass> myList = new List<MyClass>();
myList.Add(new MyClass() { Foo = "a" });
myList.Add(new MyClass() { Foo = "b" });

Or even more compactly, you can exploit the collection initialization syntax and simply:

List<MyClass> myList = new List<MyClass>() 
{
    new MyClass() { Foo = "a" },
    new MyClass() { Foo = "b" }
}

If you want to copy an object from your list, then you need to copy each property (and if it contains other objects, you may need to copy them too). There are various ways to do this, IClonable or a copy constructor are examples, but it basically comes down to, at some point, doing something like this:

myCopy.Foo = myOriginal.Foo;
myCopy.Bar = myOriginal.Bar;
// repeat for all properties that you want to copy.

Now assuming that Foo and Bar aren't also reference types, you have a copy. If they are reference types, you have a copy, but myCopy.Foo and myOriginal.Foo are still pointing at the same object.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • yes this is exactly what I'm looking at now how do I not reference it and actually create it as a new. some one vote this up for me – CKY Mar 05 '14 at 18:13
  • @CKY: what do you mean "create it as new"? If you want a new `MyClass` just `MyClass y = new MyClass()`, then set it's properties how ever you want and then add it to your collection with `myList.Add(y)`. If you wanted to *copy* another instance of `MyClass` then you need to clone the original which is simply a case of having a method that will copy each property from the old object to the new one. – Matt Burland Mar 05 '14 at 18:16
  • i tried creating a copy of the old object but met the same issue – CKY Mar 05 '14 at 18:18
  • @CKY: How are you trying to create a copy? `MyClass item = myList[1];` is not making a copy. – Matt Burland Mar 05 '14 at 18:21
  • @CKY: If any of your properties there are reference types themselves, then you've made a shallow copy, not a deep copy. – Matt Burland Mar 05 '14 at 18:30
  • they are is there something that I can call i tried icloneable but got lost this why i came here but was unsure of how to ask this – CKY Mar 05 '14 at 18:35
  • obj1 = new MyClass() { Foo = "something else" }; I tried somehting like this but was meet with an error let me try it again and get you the error – CKY Mar 05 '14 at 18:41
  • thank you very much I know how to do this now. Its going to take a lot more code then what I was hoping for but the end result will be what I need – CKY Mar 05 '14 at 18:51