Как извлечь элемент массива структуры в переменную без копирования в C#? - PullRequest
2 голосов
/ 02 апреля 2020

У меня есть небольшой вопрос о массивах struct в C#: допустим, у меня есть struct Foo:

struct Foo
{
    public string S;
    public int X;
    ...
    ...
}

и у меня есть массив Foo: Foo[] arr = ...

В одном методе я использую arr[i] довольно часто, поэтому я хотел бы сохранить его в локальной переменной (выражение для i также немного длинное):
var f = arr[i]

Теперь, моя проблема в том, что я знаю, что структуры являются типом значения, что означает, что подобные назначения вызывают копию. Структура немного большая (7 строк и тип bool), поэтому я бы предпочел избегать копирования в этом случае.

Если я не ошибаюсь, единственный способ получить доступ к полям структуры без копирования структуры это использовать массив напрямую: arr[i].S или arr[i].X, но это быстро становится раздражающим для чтения. Я действительно хотел бы сохранить элемент массива в локальной переменной, но я не хочу терять производительность, копируя его в переменную.

Есть ли способ сделать что-то вроде ссылочной переменной (аналогично в C ++), чтобы избежать копирования? Если нет, то мне интересно, оптимизирует ли это компилятор?

Как мне поступить с этим элементом? Могу ли я поместить его в локальную переменную без копирования или мне нужно обращаться к нему через массив, чтобы избежать копирования?

Заранее спасибо.

1 Ответ

5 голосов
/ 02 апреля 2020

Вы можете сделать это в C# 7 и позже, используя локальные переменные ref:

using System;


public struct LargeStruct
{
    public string Text;
    public int Number;
}

class Test
{
    static void Main()
    {
        LargeStruct[] array = new LargeStruct[5];

        // elementRef isn't a copy of the array value -
        // it's really the variable in the array
        ref LargeStruct elementRef = ref array[2];
        elementRef.Text = "Hello";

        Console.WriteLine(array[2].Text); // Prints hello
    }
}

Конечно, я обычно рекомендую избегать:

  • Большие структуры
  • изменяемые структуры
  • поля Publi c (хотя, если оно изменяемое, лучше всего делать это с помощью полей publi c)

... но я признать, что всегда есть исключения.

...