Передайте фрагмент массива значений функции в качестве ссылки

#c# #arrays #struct

Вопрос:

Мне нужно вызвать функцию ( Matrix.TransformPoints ), которая имеет массив Point ( PointF ) в качестве параметра. К сожалению, я хочу применить эту функцию только к фрагменту этого массива, и я не могу найти функцию, которая возвращает фрагмент, используя исходный исходный массив в качестве резервной копии.

Это всегда будет новый массив, и поскольку оба типа являются структурами, он будет копировать значения Point . Было бы неплохо , если бы он поддержал Span<T> , так как это помогло бы.

Для тестирования я написал этот пример. Я добавил DoSpan функцию, потому что тогда я мог бы убедиться, что DoArray(Span.ToArray()) она не работает, пока DoSpan(Span) работает. Только при передаче исходного массива в DoArray (или использовании DoSpan ) он фактически изменит значения из исходного массива.

     // Same parameters as Matrix.TransformPoints
    public static void DoArray(Point[] points)
    {
        for (int i = 0; i < points.Length; i  )
        {
            points[i].X  ;
        }
    }

    // Just to verify that with Spans it could work, but not Span.ToArray()
    public static void DoSpan(Span<Point> points)
    {
        for (int i = 0; i < points.Length; i  )
        {
            points[i].X  ;
        }
    }
    
    public static void Main()
    {
        Point[] points = new Point[4];
        DoArray(points);
        PrintArray("Complete Array", points);
        DoArray(points[2..4]);
        PrintArray("Array-Slice", points);
        DoSpan(points.AsSpan(2..4));
        PrintArray("Span", points);
        DoArray(points.AsSpan(2..4).ToArray());
        PrintArray("Span.ToArray()", points);
    }
    
    private static void PrintArray(string msg, IEnumerable<Point> points)
    {
        Console.WriteLine(msg);
        foreach (var p in points)
        {
            Console.WriteLine($"t{p}");
        }
    }
 

Теперь, если бы я программировал на C, я мог бы просто передать указатель третьему элементу, и функция не знала бы, что это срез массива (конечно, мне также нужно было бы передать длину/количество). Поэтому мне интересно, есть ли в C# что-то подобное.

Комментарии:

1. Ваш DoSpan(points.AsSpan(2..4)) звонок отлично подходит для меня, чего я и ожидал. Выходные данные после этого имеют значения X 1, 1, 2, 2 (где первый вызов установил их все на 1, а вызов DoSpan увеличил индексы 2 и 3 до значения 2). Итак, в принципе: просто используйте промежутки…

2. (Но points[2..4] создаст новый массив, а также вызовет вызов ToArray — так что не делайте ни того, ни другого.)

3. Но Matrix.TransformPoints не принимает промежутки.

4. Я отредактировал исходный пост, чтобы было понятнее, что ограничение есть Matrix.TransformPoints .

5.Хорошо, если Matrix.TransformPoints только принимает массив, то вы застряли.