You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在foreach循环中使用Point.Offset方法修改Point数组的疑问及最优方案

解决C#中Point数组的Offset修改问题

哈哈,这个问题我当初刚学C#的时候也踩过坑!核心原因是**Point是值类型**,而foreach遍历数组时拿到的是每个元素的副本——你调用Offset修改的只是这个临时副本,原数组里的Point根本不会有变化。下面给你几种靠谱的方式,把偏移后的Point正确存回MyPoints数组:

方法1:用for循环(最直接易读,完全合理)

这其实是非常正统的写法,一点都不算“不正确”,反而可读性拉满:

using System;
using System.Drawing; // 注意要引用System.Drawing命名空间

class Program
{
    static void Main()
    {
        Point[] MyPoints = { new Point(1, 1), new Point(2, 2) };
        int offsetX = 5, offsetY = 5;

        for (int i = 0; i < MyPoints.Length; i++)
        {
            // 取出数组里的Point副本
            var currentPoint = MyPoints[i];
            // 调用Offset修改副本的坐标
            currentPoint.Offset(offsetX, offsetY);
            // 把修改后的副本存回原数组的对应位置
            MyPoints[i] = currentPoint;
        }

        // 验证结果
        foreach (var p in MyPoints)
        {
            Console.WriteLine($"X: {p.X}, Y: {p.Y}");
        }
    }
}

方法2:用LINQ创建新数组(简洁的函数式写法)

如果你喜欢更简洁的代码,可以用LINQ生成修改后的新数组,再赋值回原变量:

using System;
using System.Drawing;
using System.Linq;

class Program
{
    static void Main()
    {
        Point[] MyPoints = { new Point(1, 1), new Point(2, 2) };
        int offsetX = 5, offsetY = 5;

        // 遍历每个Point,修改后生成新数组
        MyPoints = MyPoints.Select(p => 
        {
            p.Offset(offsetX, offsetY);
            return p;
        }).ToArray();

        // 验证结果
        foreach (var p in MyPoints)
        {
            Console.WriteLine($"X: {p.X}, Y: {p.Y}");
        }
    }
}

这种方式适合不需要保留原数组的场景,代码看起来更清爽。

方法3:用Span<T>高效修改(.NET Core/.NET 5+适用)

如果你的项目基于.NET Core或.NET 5及以上版本,可以用Span<T>来直接操作数组元素,避免不必要的副本,效率更高:

using System;
using System.Drawing;

class Program
{
    static void Main()
    {
        Point[] MyPoints = { new Point(1, 1), new Point(2, 2) };
        int offsetX = 5, offsetY = 5;

        // 用AsSpan()获取数组的跨度,ref var直接引用数组里的元素
        foreach (ref var p in MyPoints.AsSpan())
        {
            p.Offset(offsetX, offsetY); // 直接修改原数组的元素,无需赋值
        }

        // 验证结果
        foreach (var p in MyPoints)
        {
            Console.WriteLine($"X: {p.X}, Y: {p.Y}");
        }
    }
}

这里的ref var让我们直接拿到数组中元素的引用,调用Offset时直接修改原数组里的实例,不需要额外的赋值步骤,性能最优。

总结一下:如果追求简单易读,for循环完全是正确选择;喜欢简洁就用LINQ;追求性能的话,Span<T>是最佳方案~

内容的提问来源于stack exchange,提问作者Ndnes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:30:42