The shared list stack is cleared when the deleted list is deleted

I have a little problem when I want to perform some operations in C #. I will give you a small example.

Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>(); List<HufmannLetter> letterList = new List<HufmannLetter>(); while(true){ letterList.Add("asd"); letterList.Add("sad"); steps.Push(letterList); letterlist.Clear(); } 

In this code, I want to move my linked list onto the stack, than delete all the items in the list. When I clear the list, my first stack index disappears because it is passed by reference. Am I mistaken? Because I do not know why this is happening.

Therefore, I use the pass by value method.

 Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>(); List<HufmannLetter> letterList = new List<HufmannLetter>(); while(true) { letterList.Add("asd"); letterList.Add("sad"); List<HufmannLetter> tempLetterList = new List<HufmannLetter>(letterList); steps.Push(tempLetterList); letterlist.Clear(); } 

Is this a good way to solve the problem? Thus, it works, but readability decreases. What do you offer me?

Thanks...

+5
source share
4 answers

Just create a new List<HufmannLetter> object inside the loop and add it to the stack. Reusing the same list object will not have any benefits.

 Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>(); while(true) { List<HufmannLetter> letterList = new List<HufmannLetter>(); letterList.Add("asd"); letterList.Add("sad"); steps.push(letterList); } 
+3
source

You can create a new List<HufmannLetter>() and specify the previous list in the constructor, this will create a new object that will not be cleared.

 while(condition) { letterList.Add("asd"); letterList.Add("sad"); steps.push(new List<HufmannLetter>(letterList)); letterlist.Clear(); } 

EDIT

So, List<T> is a reference type, you letterList on the stack. Thus, you transfer the value of the List<T> link to the stack element. Thus, the letterList variable refers to the same object as the item in your stack. When you clear items from a list of letters, they are also cleared in the stack item.

Check What Link Types Are

+1
source

List<> is a mutable reference type.

When you pass the List<> method to the method, you pass a copy of the link. So you just say what List<> . This will not copy (clone) the entire contents of List<> .

When you put ( Push ) a List<> on Stack<> , what Stack<> really saves is a copy of the link to this instance of List<> . If this instance is subsequently modified, for example using .Add("asd") or .Clear() , this "mutation" will be visible if you follow the link saved by Stack<> or another link that you have from local variable. Both links "point" to the same List<> instance.

When in your code you say:

 letterList.Clear(); // do not change reference, follow reference and mutate the instance it refers to 

which will modify (mutate) an existing instance of List<> so that it becomes empty. This change will be visible to anyone who references this particular instance of List<> .

If you did:

 letterList = new List<string>(); // create new instance, change reference to point there (reference assignment), old instance is unchanged 

which "moved" the letterList link to point to a new instance of List<> . This will not affect people with other links to the "old" instance.


The name Pass By Reference Reference is misleading. It should have been link types and link passing or something like that.

+1
source

you can also do it like

 Stack<List<HufmannLetter>> steps = new Stack<List<HufmannLetter>>(); while(true) { var tempList = new List<HufmannLetter>; tempList.add("asd"); steps.push(tempList); } 

or you can try this

 steps.push(tempList.ToList()); tempList.Clear(); 
-1
source

Source: https://habr.com/ru/post/1260013/


All Articles