C # структура лучшие практики, возможные противоречия? - PullRequest
0 голосов
/ 02 сентября 2018

Я знаю, что есть примерно 1000 вопросов по структуре C #. Я хочу повторить, я понимаю семантику значений, преимущества производительности stackallocs и т. Д. Мой конкретный вопрос проистекает из этой статьи о том, когда использовать struct над классом. Структура MSDN против класса C #

Во-первых, они говорят о преимуществах встроенных данных для контейнеров, в частности массивов. Одно распределение и не определяемая пользователем инициализация по умолчанию всех структур в массиве. Тем не менее, они также подчеркивают, что структуры должны быть неизменными.

Если я объявлю mystuct[] s = new mystruct[16];, у меня будет 16 mystruct с встроенными значениями по умолчанию. Если я создал «кошерную» структуру без внешней изменчивости в соответствии с рекомендациями, как мне пригодится конструкция? Я сомневаюсь, что намереваюсь иметь массив исключительно из 0-интегралов и нулей.

Имеют ли они в виду неизменность при функционировании в качестве записи или только при возврате свойства, т. Е. При передаче отдельных данных?

Если конкретный конфликт между инициализацией массива по умолчанию и рекомендованной неизменяемостью уже обсуждался ранее, отметьте его как дубликат. Спасибо за понимание.

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Об неизменяемости, о которой идет речь, являются методы структуры, а не значение самой структуры. Экземпляр структуры всегда может быть видоизменен посредством присваивания - подумайте о переменной целочисленного цикла в цикле for; он изменяется при каждом прохождении цикла.

Но для структуры System.Int32 структуры (т. Е. int) не имеет смысла иметь метод DoubleIt, который заставляет базовое целое число удваивать свое значение без какой-либо очевидной операции присваивания (например, как ++i; на самом деле i=i+1;).

Рассмотрим разницу между string.Replace и StringBuilder.Replace. Класс System.String является неизменным. Метод Replace для строки возвращает новый экземпляр строки, который представляет исходную строку после операции замены. StringBuilder's Replace выполняет замену на месте, изменяя внутренний объект.

Итак, если я создаю целочисленный массив:

var ar = new int[] {1, 2, 3, 4};

Я всегда могу изменить содержимое этого массива (экземпляр System.Array, ссылочный тип) путем присвоения массива:

 ar[2] = 200;

Что не имеет смысла, так это вызывать какой-либо метод мутации для этого (целочисленного) элемента массива.

0 голосов
/ 02 сентября 2018

Фактического противоречия между ними нет:

после того, как вы выполните var s = new mystruct[16];, это правда, что у вас есть массив из 16 экземпляров mystruct, инициализированный значением по умолчанию.

Однако, выполнение s[0] = new mystruct(<arguments list here>) не изменяет структуру в первой ячейке массива, оно заменяет ее новой структурой.

Таким образом, сама структура все еще неизменна.

...