В C# индексатор `[]` массива структур возвращает копию?C#

Место общения программистов C#
Ответить
Anonymous
 В C# индексатор `[]` массива структур возвращает копию?

Сообщение Anonymous »

Я работаю над проектом, в котором нам нужно использовать массивы Vector3 и массивы Quaternion из System.Numerics и реализованы как структуры. На самом деле нам нужно обращаться к массивам и изменять значения отдельных элементов, т. е. они являются изменяемыми структурами.
Я прочитал лекцию о том, что «изменяемые структуры — это зло», но это кажется неизбежным, если я не скопирую исходный код Quaternion.cs и Vector3.cs в свой проект и не изменю их на классы в частной реализации, или не напишу классы-оболочки, или что-то столь же ужасное, поэтому я я страдаю чтобы понять подводные камни изменяемых структур. Часто цитируется блог Эрика Липперта «Мутация структур, доступных только для чтения», и я уверен, что у нас не возникнет проблем с приведенным им примером классов, имеющих поля изменяемых структур, доступных только для чтения; но в разделе комментариев Эрик говорит:

Например, что-то вроде: mydictionary[123].blah = 456; — это ошибка компилятора если индексатор возвращает изменяемую структуру. Результат индексатора не является переменной, и поэтому запись в blah будет осуществляться в копии, возвращаемой индексатором, а не в содержимом словаря. Это явно совсем не то, что имел в виду автор. Они имели в виду temp = mydictionary[123]; темп.бла = 456; мой словарь[123] = temp;. Поскольку код явно поддельный и существует простой обходной путь, мы выдаем ошибку.

Конечно, этот комментарий от 2008 года, и, возможно, он просто неверен. В настоящее время больше не применяю. Если да, то что изменилось?
Мне действительно нужно это сделать, но Эрик говорит: "

Код: Выделить всё

mydictionary
", подразумевая, что это словарь, и я использую массивы, поэтому, возможно, индексатор массивов считается "переменными", а индексатор словарей - нет, т. е. они работают по-разному друг от друга, но, по моему опыту, это не проблема:

Код: Выделить всё

    var quaternions = new Quaternion[100, 100];
Console.WriteLine(quaternions[1, 1].X);  // Outputs "0"
quaternions[1, 1].X = 1.0f;
Console.WriteLine(quaternions[1, 1].X);  // Outputs "1"
Итак, индексатор возвращает копию или нет? Ввели ли они некоторый синтаксический сахар, чтобы этот код фактически компилировался для создания локальной копии, изменения ее и копирования обратно? Мне бы не хотелось так тратить ресурсы процессора.
Я все еще пытаюсь убедиться, что понимаю, каким образом изменяемые структуры вызывают проблемы и заслужили плохую репутацию, чтобы мы могли их использовать. правильно. Я понимаю, что «по умолчанию при назначении, передаче аргумента методу и возврате результата метода копируются значения переменных». Типы значений (справка по C#). Если это действительно все, о чем мне нужно беспокоиться, я думаю, что хорошо с этим разбираюсь, но комментарии в блоге Эрика и мои наблюдения в реальности вселяют во меня неуверенность.
В конкретная спецификация говорит в доступе к массиву:

Расположение элемента массива, заданное выражением индекса, вычисляется, и это местоположение становится результатом доступ к массиву.

Это, кажется, подтверждает, что индексация массивов возвращает ссылку, а не значение.
Изменить:
Добавление дополнительной информации.
На https://stackoverflow.com/a/6691740/1726692 есть пример доступа к элементам массива, который работает нормально, как и мой пример. Но они отмечают, что каждый массив Array реализует IList, поэтому, если вы просто преобразуете этот массив в IList и повторяете ту же операцию, вы работаете с копией элемента, а не обращаетесь к нему. сам элемент. Между этим ответом и ответом Марка ниже, я предполагаю, что индексатор Array не создает копию, но, вероятно, все остальные индексаторы (список, словарь и т. д.), вероятно, возвращают копии. Это все еще вопрос; в ожидании какого-либо авторитетного полного ответа.

Подробнее здесь: https://stackoverflow.com/questions/753 ... urn-a-copy
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»