I'm from a C++ background and now I'm working quite a bit more with C# so I'm learning new things all the time. One thing that baffled me recently was caused by the difference between structs and classes in C#.

In C++ the only difference between struct and class is the default member accessibility. For example, in the code below A::f() is private, whereas B::f() is public

class A
{
   
void f();
}

struct B
{
   
void f();
}

That's the only difference. Structs can have member functions and classes can contain only data members. For C#, things are different, as I found out recently.

In C#, structs are always passed by value, whereas classes are always passed by reference. What this means in practice is that anywhere you pass a struct to a function as a parameter or return it you are doing so by value.

The confusing piece of code for me was equivalent to the following:

struct Animal
{
   
public int Spots;
}

class Program
{
   
static void Main(string[] args)
    {
       
List<Animal> allAnimals = new List<Animal>();
        allAnimals.Add(
new Animal());
        allAnimals.Add(
new Animal());

       
foreach (Animal animal in allAnimals)
        {
            animal.Spots = 5;
       
}
      
Debug.WriteLine(String.Format("First animal spots: {0}", allAnimals[0].Spots));
    }
}

When I compiled the code above I got the error:

error CS1654: Cannot modify members of 'animal' because it is a 'foreach iteration variable'

How strange, I thought. OK, maybe in a foreach loop you can't modify public members. Let's try calling a function instead: 

struct Animal
{
    public void setSpots(int NewSpots)
   
{
        Spots = NewSpots;
    }
   
public int Spots;
}

class Program
{
   
static void Main(string[] args)
    {
       
List<Animal> allAnimals = new List<Animal>();
        allAnimals.Add(
new Animal());
        allAnimals.Add(
new Animal());

       
foreach (Animal animal in allAnimals)
        {
            animal.setSpots(5);
       
}
      
Debug.WriteLine(String.Format("First animal spots: {0}", allAnimals[0].Spots));
    }
}

So the compile error went away, but the message printed out was:

First animal spots: 0

I was expecting 5 here. After reading a little bit about structs and classes in C#, the penny dropped. Each iteration through allAnimals was getting a copy of the animal and calling setSpots. If I changed the definition of Animal to a class instead of struct, I could use the original code.

class Animal
{
   
public int Spots;
}

class Program
{
   
static void Main(string[] args)
    {
       
List<Animal> allAnimals = new List<Animal>();
        allAnimals.Add(
new Animal());
        allAnimals.Add(
new Animal());

       
foreach (Animal animal in allAnimals)
        {
            animal.Spots = 5;
       
}
      
Debug.WriteLine(String.Format("First animal spots: {0}", allAnimals[0].Spots));
    }
}

Incidentally, members of structs also do not have default public accessibility in C#.