C # с использованием метода смещения точек в цикле foreach для изменения массива точек - PullRequest
0 голосов
/ 25 апреля 2018

У меня проблемы с пониманием того, как метод смещения точек работает в цикле 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*/

1 Ответ

0 голосов
/ 25 апреля 2018

System.Drawing.Point - это структура - тип значения.Цикл foreach копирует значение Point из коллекции в переменную p.Затем вы изменяете переменную p, вызывая Offset, но это совсем не меняет коллекцию, потому что изменяется только копия .

Во втором цикле,вы изменяете значение в массиве напрямую - вот почему вы видите разницу.

Более идиотский способ сделать это:

for (int i = 0; i < MyPoints.Length; i++)
{
    MyPoints[i].Offset(5, 2);
}

Стоит отметить, чтоPoint относительно необычен, так как это тип значения mutable - метод Offset действительно изменяет значение.Большинство типов значений (например, DateTime) являются неизменяемыми - такие методы, как AddDays, не изменяют значение, к которому они обращаются;вместо этого они возвращают новое значение.Таким образом, чтобы сделать нечто подобное с массивом дат, вам понадобится такой код:

for (int i = 0; i < dates.Length; i++)
{
    dates[i] = dates[i].AddDays(10);
}

Или вы можете использовать LINQ для создания нового массива:

DateTime[] newDates = dates.Select(date => date.AddDays(10)).ToArray();

Вы не могли быне пишите точно так же для Point, потому что Offset возвращает void.Вам нужно что-то вроде:

Point[] newPoints = points.Select(point => { point.Offset(5,2); return point; })
                          .ToArray();
...