C#在foreach循环中使用点的偏移方法来修改点数组
C# using points' offset method in foreach loop to modify array of points
我无法理解点的偏移方法如何在 foreach 循环中工作以修改现有的点数组。我可以通过手动索引每个数组实体来做到这一点,但我强烈怀疑不应该这样做。
*编辑要清楚。将我的偏移点存储在 MyPoints 数组中的最佳方式是什么?
见下面的代码。我使用 http://rextester.com/ 在线 C# 编译器来测试代码。
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
是一种结构——一种值类型。 foreach
循环将 Point
值从集合中复制到 p
变量中。然后,您通过调用 Offset
修改 p
变量,但这根本不会更改集合,因为它只是修改了 copy。
在你的第二个循环中,你直接修改数组中的值 - 这就是你看到差异的原因。
更惯用的方法是:
for (int i = 0; i < MyPoints.Length; i++)
{
MyPoints[i].Offset(5, 2);
}
值得注意的是 Point
相对不常见,因为它是一个 可变 值类型 - Offset
方法确实改变了值。大多数值类型(例如 DateTime
)是不可变的——像 AddDays
这样的方法不会修改它们被调用的值;相反,他们 return 一个 新的 值。因此,要对日期数组执行类似的操作,您需要这样的代码:
for (int i = 0; i < dates.Length; i++)
{
dates[i] = dates[i].AddDays(10);
}
或者您可以使用 LINQ 创建一个新数组:
DateTime[] newDates = dates.Select(date => date.AddDays(10)).ToArray();
由于 Offset
returns void
的方式,您不能完全像 Point
那样写。你需要这样的东西:
Point[] newPoints = points.Select(point => { point.Offset(5,2); return point; })
.ToArray();
我无法理解点的偏移方法如何在 foreach 循环中工作以修改现有的点数组。我可以通过手动索引每个数组实体来做到这一点,但我强烈怀疑不应该这样做。
*编辑要清楚。将我的偏移点存储在 MyPoints 数组中的最佳方式是什么?
见下面的代码。我使用 http://rextester.com/ 在线 C# 编译器来测试代码。
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
是一种结构——一种值类型。 foreach
循环将 Point
值从集合中复制到 p
变量中。然后,您通过调用 Offset
修改 p
变量,但这根本不会更改集合,因为它只是修改了 copy。
在你的第二个循环中,你直接修改数组中的值 - 这就是你看到差异的原因。
更惯用的方法是:
for (int i = 0; i < MyPoints.Length; i++)
{
MyPoints[i].Offset(5, 2);
}
值得注意的是 Point
相对不常见,因为它是一个 可变 值类型 - Offset
方法确实改变了值。大多数值类型(例如 DateTime
)是不可变的——像 AddDays
这样的方法不会修改它们被调用的值;相反,他们 return 一个 新的 值。因此,要对日期数组执行类似的操作,您需要这样的代码:
for (int i = 0; i < dates.Length; i++)
{
dates[i] = dates[i].AddDays(10);
}
或者您可以使用 LINQ 创建一个新数组:
DateTime[] newDates = dates.Select(date => date.AddDays(10)).ToArray();
由于 Offset
returns void
的方式,您不能完全像 Point
那样写。你需要这样的东西:
Point[] newPoints = points.Select(point => { point.Offset(5,2); return point; })
.ToArray();