using static System.Console;
using System.Collections.Generic;
public class Program {
public static void Main(string[] args) {
var list = new List<Item>() {
new Item() { Nome = "GPU" },
new Item() { Nome = "Livro" }
};
list.Add(new Item() { Nome = "Cadeira" });
var item = new Item() { Nome = "Abóbora" };
list.Add(item);
var carro = new Item() { Nome = "Carro" };
list.Add(carro);
item = new Item() { Nome = "Outro objeto" };
list.Add(item);
list.Add(carro);
for (int i = 0; i < list.Count; i++) {
WriteLine($"Item: {list[i].Nome}");
}
}
}
public class Item {
public string Nome;
}
Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.
I wasn’t adding different items, I was adding the same item, so it was only the last value. You have to create a new item to add to the list. When:
itens.nome = "Livro";
was changing the value of the same object created before, so the previous item pointed to this same object, but now with a new value.
This is because classes are types by reference, so what you have in the variable is a pointer to the object elsewhere. It seems like two things, but it’s the same. If it were one struct
then it would be different, so that if it were an integer the same would not occur. Read more in What’s the difference between Struct and Class?.
Note that I have introduced new ways to write this. When you create the list you can already create the items inline and start the list already with the items.
Then I added a new item creating it inline again, that is, you do not need to create a variable for it. Nor do you need to assign values to its members after the object was created.
But I also did it with the variable creation if it is important. Again, you have to create a new object.
Let’s say you want another variable that holds an object and add a reference to this object in the list, I did this with carro
.
Finally, I created a new item in the same variable. Of course the variable loses the reference to the previous object, but I showed that the important thing is to create the new object and not the variable.
I still added the variable carro
again, even without touching the object. It is the same object being added, it is not another. If you touch this object, the two entries in the list will be affected because they reference the same object.
If you know the pointers of C, that’s it. Types by reference are always pointers to objects. Types by value are objects themselves. In C# it becomes more abstract, but the internal mechanism is equal to C.
Then note that your itens
is not an object, is a variable that has a value, in the case of a pointer, the object is not in items. It is a common mistake for people to think that variables always hold objects. This is only true in types per value.
I changed the name of the class that makes more sense, it is only one item, the list is that are several items.
This is because it inserts the reference to the object, not the object itself. When you insert, you need to create a new reference for the object
Itens
, with thenew
.– Felipe Avelar
Imagine that each item is a box. What you will add is a reference to where this box is in the list (not the box itself).
new
does is "create a new box" to store this information and, consequently, a new reference to where you can find it.– Felipe Avelar
Like the C pointers, right?
– underfilho
Basically, yes.
– Felipe Avelar