Variable of the foreach loop

Asked

Viewed 1,582 times

8

When we use a loop loop foreach, the local variable we create to receive the contents of the list in question is passed by value or reference?

Ex:

foreach (var item in listItems)
{
   //TODO
}

The variable item receives the content by value or reference?

  • each time a loop is made, the variable item receives one of the items on listItems. I don’t quite understand your question

  • right @Italorodrigo but the information is received by Value or Reference?

  • 1

    I believe the list object reference is passed.

  • Milton, it’s not always by value. It’s only by value if the list is a primitive type - see my answer. If it is a complex type list, it will be by reference.

  • @It’s always worth it.

  • It is not by value, by value means a copy of the data, and it is not what happens.

Show 1 more comment

2 answers

12


The item is by value, so it is not even allowed to change its value.

There’s only one detail, if the item is an object by reference that value I’m talking about is pointer and not the object itself, then you can modify the object normally, only you can’t change the constant reference in the collection, that is, you can’t change the object as a whole to a new one, but can modify the existing.

There is a proposal to say that the item should be by reference and bring all the good and bad consequences of it.

using static System.Console;
using System.Collections.Generic;

public class Program {
    public static void Main() {
        var ints = new List<int> { 1, 2, 3 };
        var lists = new List<List<int>> { new List<int> { 1, 2, 3 }, new List<int> { 4, 5, 6 } };
        foreach (var item in ints) {
//          item = 9; //não compila
        }
        foreach (var item in lists) {
            item[0] = 9;
        }
        foreach (var item in lists) {
//          item = new List<int> { 7, 8, 9 }; //não compila
        }
        foreach (var lista in lists) {
            foreach (var item in lista) {
                WriteLine(item);
            }
        }
    }
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

Behold Memory allocation in C# - Value types and reference types. And also: What are and where are the "stack" and "heap"?. Will also help What’s the difference between Struct and Class?.

There is a lot of confusion between programmers, and especially in the world. NET, on the use of memory, so it would be interesting to deepen the concepts about types by value and reference, where they are allocated, what can be done with it, and about immutability that people usually associate with types by value (which some call primitive, but this concept does not exist in C#), but these types may be immutable, or associate what types by reference are mutable and they may be immutable, see more in The use of immutability.

  • Then the item will behave according to the collection type.

  • Yes, it depends on the type of items in the collection. This does not change anything in relation to other aspects of the language. Everything is value in language, the difference is that types by value have their object directly, and types by reference have as their value a pointer to an external object, that is to say indirectly. It is not possible to change a value without changing the identity, but it is possible to change a referenced object and maintain the identity, as long as its composition thus allows, an example of what is not so is the string. Changing a character in it changes the identity and reference,

  • port does not allow changing its value within the foreach.

2

Depends on what kind the list is.

If it’s a complex kind of list - class - shall be by reference.

If it’s a primitive type list - string, int, bool, decimals, etc - will be by value. However, you cannot change the value of that variable because it is an iteration variable of the foreach.

TL;DR;

This is due to the fact that primitive variables are allocated in memory other than complex types. There are two types of memory that you should worry about while developing:

  • Memory Stack: Fast access memory and simple value allocation;
  • Memory Heap: Not-so-fast access memory for complex value allocation;

When creating a primitive type variable - int, long, string, decimal, float, double, etc - this is addressed to an address in memory stack, and this address has allocated a value simple.

When an object is instantiated to a variable - new class(); - occurs as follows: the variable will reference an address in memory stack, but this address will reference is an address in memory heap, and that’s where all the values of your complex type will be.

See the image below:

inserir a descrição da imagem aqui

When you make a foreach in a complex type list, it occurs that a new variable is created in memory stack calling for item this only has its reference changed to the list items. Thus, the foreach is for reference.

But if it’s a primitive type list, that’s not possible, and you end up doing the foreach for value.

I hope to have clarified everything in this question. If something else was missing, comment. :)

Simplifying

Make a loop like the one below:

foreach(var item in list) 
{ 
    /* aqui vai seu código */ 
}

IS almost what to do (this almost is relevant):

for(var i = 0; i < list.Length; i++)
{
     var item = list[i];
     /* aqui vai seu código */ 
}

But the foreach is much more elegant. :)

Microsoft Documentation - foreach-in (C# Ference)

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in

  • Those who have spoken out, please.

  • 3

    It was not I who denied it, but your answer is wrong or at least it lacks details. Even if it is a class, it will be by value, what happens is that this value is equivalent to the pointer of the object. That is, it is a value, but this value is the reference. For this reason it is possible to modify the object, but it is not possible to change it using a = new Algo() or = null, for example.

  • I just worked out my answer. See if it improves the defense.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.