Структурные типы в C # или других языках .net обычно используются для хранения вещей, которые должны вести себя как группы значений фиксированного размера. Полезный аспект структурных типов заключается в том, что поля экземпляра структурного типа можно изменить, изменив место хранения, в котором он хранится, и никак иначе. Можно закодировать структуру таким образом, что единственный способ изменить любое поле - это создать совершенно новый экземпляр, а затем использовать присвоение структуры, чтобы изменить все поля цели, перезаписав их значениями из нового экземпляра, но если структура не предоставляет средств для создания экземпляра, в котором ее поля имеют значения не по умолчанию, все ее поля будут изменяемыми, если и если сама структура хранится в изменяемом месте.
Обратите внимание, что можно спроектировать тип структуры так, чтобы он по существу вел себя как тип класса, если структура содержит частное поле типа класса и перенаправляет своих собственных членов на объект обернутого класса. Например, PersonCollection
может предлагать свойства SortedByName
и SortedById
, которые оба содержат «неизменяемую» ссылку на PersonCollection
(установленную в их конструкторе) и реализуют GetEnumerator
, вызывая либо creator.GetNameSortedEnumerator
, либо creator.GetIdSortedEnumerator
. Такие структуры будут вести себя как ссылка на PersonCollection
, за исключением того, что их GetEnumerator
методы будут связаны с различными методами в PersonCollection
. Можно также иметь структуру, заключающую в себе часть массива (например, можно определить структуру ArrayRange<T>
, которая будет содержать T[]
с именем Arr
, int Offset
и int Length
с индексированными свойство, которое для индекса idx
в диапазоне от 0 до Length-1
будет иметь доступ к Arr[idx+Offset]
). К сожалению, если foo
является экземпляром такой структуры, доступным только для чтения, текущие версии компилятора не будут разрешать такие операции, как foo[3]+=4;
, потому что у них нет способа определить, будут ли такие операции пытаться записывать в поля foo
.
Также возможно спроектировать структуру, которая будет вести себя как тип значения, который содержит коллекцию переменного размера (которая будет копироваться всякий раз, когда структура), но единственный способ выполнить эту работу - убедиться, что никакой объект на которую структура содержит ссылку, будет когда-либо подвергаться чему-либо, что может ее изменить. Например, можно иметь массивоподобную структуру, которая содержит закрытый массив, и чей индексированный метод «put» создает новый массив, содержимое которого аналогично содержимому оригинала, за исключением одного измененного элемента. К сожалению, может быть довольно сложно заставить такие структуры работать эффективно. Хотя бывают случаи, когда семантика структуры может быть удобной (например, возможность передавать массивоподобную коллекцию в подпрограмму, когда вызывающая сторона и вызываемая сторона знают, что внешний код не будет изменять коллекцию, это может быть лучше, чем требовать и вызывающую, и требование защищенного копирования любых данных, которые им предоставляются), требование, чтобы ссылки на классы указывали на объекты, которые никогда не будут видоизменяться, часто является довольно серьезным ограничением.