I have the following code inside main method:
List<Rectangle> rects = new List<Rectangle>(); for (int i = 0; i < 5; i++) { rects.Add(new Rectangle(1, 1, 1, 1)); } foreach (Rectangle item in rects) { Console.WriteLine(item); } rects[1].Inflate(100, 100); foreach (Rectangle item in rects) { Console.WriteLine(item); }
In the presented code rects[1] remains unchanged. This is because indexer (which still is a special method) returned the copy of the rectangle structure. In this case the elements were located on heap. The indexer returned the new copy of the element by placing the new copy on the stack (since the Rectangle is a value type).
So far so good…
Later I have created an array of Rectangle structures in the Program class:
Rectangle[] rect = new Rectangle[] { new Rectangle(1, 1, 1, 1), new Rectangle(1, 1, 1, 1) };
In the main method:
Program p = new Program(); p.rect[1].Inflate(100, 100); foreach (var item in p.rect) { Console.WriteLine(item); }
I expected the indexer of rect array also to return copy of the rectangle structure, but this time the original element (which was also located on the heap) was changed.
Why is that? Does the array indexer works in a different way?
Kind Regards PK
From this you conclude that the indexer on a list is a method call that places the value of a value type on the stack when returning from a method and that the array indexer is actually translated in code to the calculation of an offset from the start of the array and is a direct memory reference.