You need to enable JavaScript to run this app. C#如何向接收数组参数的函数传入值类型数组的引用切片
优惠活动
大模型
产品
解决方案
定价
更多

C#如何向接收数组参数的函数传入值类型数组的引用切片

解决方案

C#目前有两类可落地的实现方案,适配不同的使用场景:

方案1:全版本兼容的临时数组回拷方案

不需要开启不安全代码,兼容所有.NET Framework/.NET版本,是标准实现方式:

  • 从原数组切片位置拷贝对应数量的Point/PointF到临时数组
  • 将临时数组传入Matrix.TransformPoints执行变换
  • 把变换后的临时数组元素回写到原数组的对应切片位置

如果切片操作很频繁,可以复用固定大小的临时数组,避免反复分配内存带来的GC开销。
示例代码如下:

public static void TransformPointsSlice(this Matrix matrix, Point[] source, int startIndex, int length)
{
    // 可复用全局临时数组代替每次new,进一步优化性能
    Point[] temp = new Point[length];
    Array.Copy(source, startIndex, temp, 0, length);
    matrix.TransformPoints(temp);
    Array.Copy(temp, 0, source, startIndex, length);
}

// 调用示例:处理索引2到3的切片
matrix.TransformPointsSlice(points, 2, 2);

方案2:零拷贝高性能实现

因为官方Matrix.TransformPoints没有提供Span/指针重载,要实现完全无拷贝的操作,可以直接基于矩阵变换的数学逻辑实现自定义方法,性能最优,实现逻辑也非常简单:

public static void TransformPointsSpan(this Matrix matrix, Span<Point> points)
{
    // 获取矩阵的六个元素:M11, M12, M21, M22, OffsetX, OffsetY
    float m11 = matrix.Elements[0], m12 = matrix.Elements[1];
    float m21 = matrix.Elements[2], m22 = matrix.Elements[3];
    float dx = matrix.Elements[4], dy = matrix.Elements[5];
    
    for (int i = 0; i < points.Length; i++)
    {
        int x = points[i].X, y = points[i].Y;
        points[i].X = (int)(x * m11 + y * m21 + dx);
        points[i].Y = (int)(x * m12 + y * m22 + dy);
    }
}

// 调用示例:零拷贝直接修改原数组切片
matrix.TransformPointsSpan(points.AsSpan(2, 2));

如果项目允许开启不安全代码,也可以用和C语言完全一致的指针偏移逻辑操作内存,配合栈内存分配可以大幅降低小切片场景的性能开销。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 21:39:01