dgamma3
dgamma3

Reputation: 2371

C# variable reference confusion

Here is the example code:

List<List<Pet>> petsList = new List<List<Pet>>();

List<Pet> pets = new List<Pet>()
{
    new Pet {Name = "Whiskers"},
    new Pet {Name = "Boots"},
    new Pet {Name = "Bradley"},
};
petsList.Add(pets);

pets = pets.OrderBy(pet => pet.Name).ToList();

foreach (Pet pet in petsList[0])
{
    Console.WriteLine("{0}", pet.Name);
} 

the complete code can be found here:https://pastebin.com/raw/uB2B7A9g

The ouput of this code is not what I would have expected.

I would have expected: Boots Bradley Whiskers

But the actual output is: Whiskers Boots Bradley

isn't pets just a pointer?

so if I add pets to the petsList, and then modify pets, then petsList[0] should point to the modified variable?

But this is not the case, petsList[0] points to the unmodified pets variable.

the only way to fix this is to do:

List<List<Pet>> petsList = new List<List<Pet>>();

List<Pet> pets = new List<Pet>()
{
    new Pet {Name = "Whiskers"},
    new Pet {Name = "Boots"},
    new Pet {Name = "Bradley"},
};

pets = pets.OrderBy(pet => pet.Name).ToList();

petsList.Add(pets);

foreach (Pet pet in petsList[0])
{
    Console.WriteLine("{0}", pet.Name);
}

Upvotes: 0

Views: 88

Answers (2)

Fabio
Fabio

Reputation: 32445

isn't pets just a pointer?

Yes, pets is reference type

so if I add pets to the petsList, and then modify pets, then petsList[0] should point to the modified variable?

Correct in case when you "modify pets".
But line pets.OrderBy(pet => pet.Name).ToList(); will not modify existed collection, instead it will return new instance of List<Pet>.

So in your sample petsList[0] will still reference to the original collection, where pets after ordering will reference to new collection.

For modifying existed collection you can use List.Sort method, but because you collection is collection of type Pet - you need create custom comparer for this type. Without custom comparer items will be sorted by reference.

Upvotes: 2

Samvel Petrosov
Samvel Petrosov

Reputation: 7696

You problem is not with the equality of the references after Add(). If you add this checking for the Reference Equality you will see where is the problem:

petsList.Add(pets);
Console.WriteLine(object.ReferenceEquals(petsList[0],pets)); // true
pets = pets.OrderBy(pet => pet.Name).ToList();
Console.WriteLine(object.ReferenceEquals(petsList[0], pets)); // false

When you write pets = pets.OrderBy(pet => pet.Name).ToList(); you are changing the reference to which the pets was bound and after that petsList[0] and pets are not equal by reference any more. So you will need to set petsList[0] to that new reference also.

Upvotes: 2

Related Questions