Yes, it is.
When u use a foreach in some container what you are doing is iterating over a “thing” that implements a version of IEnumerable and to access elements this container provides a Current property that has a get but not a set, which means that items are readonly. But let’s see some code
Let’s say that we an value and an ref kind of structure
public class RefObject
{
public int field;
public RefObject(int value)
{
this.field = value;
}
}
public struct ValueObject
{
public int field;
public ValueObject(int value)
{
this.field = value;
}
}
If u try to iterate and change fields with foreach with
static void Main(string[] args)
{
var refList = new List<RefObject>{new RefObject(1), new RefObject(2), new RefObject(3)};
var valueList = new List<ValueObject>{new ValueObject(1), new ValueObject(2), new ValueObject(3)};
foreach (var item in refList)
{
item.field++;
}
// ERRO: does NOT compile
// foreach (var item in valueList)
// {
// item.field++;
// }
System.Console.WriteLine("Ref:");
refList.ForEach(x => System.Console.Write($"{x.field} "));
System.Console.WriteLine();
System.Console.WriteLine("Value:");
valueList.ForEach(x => System.Console.Write($"{x.field} "));
}
If u run above code, u’ll see that the first foreach really changed fields in ref type, this is because u are working with reference types, so u are never actually touching the container because all that container is storing is references to objects. If u try something like
item = new RefObject(0)
*inside ur first foreach
u’ll get that same error that we have when working with structs, because now u are really chaging information (AKA: references) in the container. In a container of a value type (second foreach), the container really have all information contained in struct, so any change in an element will change the container info.
And only to finish, as @MaskedMouse said Vector3 is a struct
References:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/statements#the-foreach-statement