I am having trouble understanding how points' offset method works within a foreach loop to modify an existing array of points. I am able to do it by manually indexing each array entity, but I strongly suspect that is not how it should be done.
*Edit To be clear. What is the best way to store my offset points in MyPoints array?
See code below. I used http://rextester.com/ online C# compiler to test the code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Drawing;
namespace Rextester
{
public class Program
{
static int ii = 0;
public static void Main(string[] args)
{
Point[] MyPoints =
{
new Point(0,0),
new Point(10,10),
new Point(20,0)
};
foreach(Point p in MyPoints)
{
p.Offset(5,2); //this works but does not store the new points
} //in MyPoints array when the foreach loop
//exits, which is what I want.
Console.WriteLine("p1x = {0} \t p1y = {1}", MyPoints[0].X, MyPoints[0].Y);
Console.WriteLine("p2x = {0} \t p2y = {1}", MyPoints[1].X, MyPoints[1].Y);
Console.WriteLine("p3x = {0} \t p3y = {1} \n", MyPoints[2].X, MyPoints[2].Y);
foreach(Point p in MyPoints)
{
MyPoints[ii].Offset(5,2);
ii++;
}
Console.WriteLine("p1x = {0} \t p1y = {1}", MyPoints[0].X, MyPoints[0].Y);
Console.WriteLine("p2x = {0} \t p2y = {1}", MyPoints[1].X, MyPoints[1].Y);
Console.WriteLine("p3x = {0} \t p3y = {1}", MyPoints[2].X, MyPoints[2].Y);
}
}
}
//This yields the following
/*
p1x = 0 p1y = 0
p2x = 10 p2y = 10
p3x = 20 p3y = 0
p1x = 5 p1y = 2
p2x = 15 p2y = 12
p3x = 25 p3y = 2*/
System.Drawing.Point
is a structure - a value type. The foreach
loop copies the Point
value out of the collection into the p
variable. You then modify the p
variable by calling Offset
, but that doesn't change the collection at all, because it's only the copy that's modified.
In your second loop, you're modifying the value in the array directly - which is why you're seeing the difference.
A more idiomatic way of doing that would be:
for (int i = 0; i < MyPoints.Length; i++)
{
MyPoints[i].Offset(5, 2);
}
It's worth noting that Point
is relatively unusual as it's a mutable value type - the Offset
method really changes the value. Most value types (e.g. DateTime
) are immutable - methods like AddDays
don't modify the value they're called on; instead they return a new value. So to do something similar with an array of dates, you'd need code like this:
for (int i = 0; i < dates.Length; i++)
{
dates[i] = dates[i].AddDays(10);
}
Or you could use LINQ to create a new array:
DateTime[] newDates = dates.Select(date => date.AddDays(10)).ToArray();
You couldn't write it exactly like that for Point
because of the way Offset
returns void
. You'd need something like:
Point[] newPoints = points.Select(point => { point.Offset(5,2); return point; })
.ToArray();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With