Я прочитал лекцию о том, что «изменяемые структуры — это зло», но это кажется неизбежным, если я не скопирую исходный код 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
Мобильная версия