Другой способ взглянуть на это - вместо того, чтобы просто цитировать спецификацию, в которой говорится, что структуры не могут / не имеют деструкторов, - подумать, что произойдет, если спецификация будет изменена таким образом, чтобы они это сделали - или, скорее, давайте спросимвопрос: можем ли мы угадать , почему разработчики языка решили не разрешать структурам иметь «деструкторы»?
(Не зацикливайтесь на слове «деструктор»)здесь, мы в основном говорим о магическом методе для структур, который вызывается автоматически, когда переменная выходит из области видимости. Другими словами, языковая функция, аналогичная деструкторам C ++.)
Первое, что нужно понять, эточто мы не заботимся об освобождении памяти.Находится ли объект в стеке или в куче (например, структура в классе), память рано или поздно позаботится о том или ином виде;либо выскочив из стека или собрав.Настоящая причина для того, чтобы иметь что-то, похожее на деструктор, в первую очередь заключается в управлении внешними ресурсами - такими вещами, как файловые дескрипторы, оконные дескрипторы или другие вещи, которые требуют специальной обработки, чтобы очистить их, что сам CLRне знает о.
Теперь предполагается, что у структуры есть деструктор, который может выполнять эту очистку.Хорошо.Пока вы не поймете, что когда структуры передаются как параметры, они передаются по значению: они копируются.Теперь у вас есть две структуры с одинаковыми внутренними полями, и они обе собираются попытаться очистить один и тот же объект.Сначала произойдет одно, и поэтому код, использующий другой впоследствии, начнет таинственным образом завершаться сбоем ... и затем произойдет сбой его собственной очистки (надеюсь! - в худшем случае это может привести к удалению другого случайного ресурса - это можетслучается в ситуациях, когда значения дескриптора используются повторно, например.)
Можно предположить особый случай для структур, являющихся параметрами, чтобы их «деструкторы» не запускались (но будьте осторожны - теперь вам нужнопомните, что при вызове функции, всегда является внешним, который «владеет» реальным ресурсом - так что теперь некоторые структуры немного отличаются от других ...) - но тогда у вас все еще есть эта проблема с обычными переменными структуры, где можноприсваивается другому, делая копию.
Возможно, вы могли бы обойти это, добавив специальный механизм для операций присваивания, который каким-то образом позволяет новой структуре согласовывать владение базовым ресурсом с его новой копией - возможно, они делятся имили передать право собственности outrот старого к новому - но теперь вы по сути отправились в C ++ - землю, где вам нужны конструкторы копирования, операторы присваивания и добавили кучу тонкостей, ожидающих, чтобы поймать незнакомого начинающего программиста.И имейте в виду, что весь смысл C # состоит в том, чтобы как можно больше избегать такого типа сложности в стиле C ++.
И просто, чтобы сделать вещи немного более запутанными, как указывал один из других ответовСтруктуры не просто существуют как локальные объекты.С местными жителями область видения хороша и хорошо определена;но структуры также могут быть членами объекта класса.Когда в этом случае должен вызываться «деструктор»?Конечно, вы можете сделать это, когда класс контейнера будет завершен;но теперь у вас есть механизм, который ведет себя очень по-разному в зависимости от того, где находится структура: если структура является локальной, она запускается сразу в конце области видимости;если структура находится внутри класса, она запускается лениво ... Так что если вы действительно заботитесь о том, чтобы какой-то ресурс в одной из ваших структур был очищен в определенное время, и если ваша структура могла бы в конечном итоге стать членомкласс, вам, возможно, понадобится что-то явное, например IDisposable / using (), чтобы убедиться, что ваши основы покрыты.
Так что, хотя я не могу утверждать, что говорю от имени языковых дизайнеров, я могу сделатьДовольно неплохо догадаться, что одна из причин, по которой они решили не включать такую функцию, заключается в том, что это будет червячная банка, и они хотели сохранить C # достаточно простым.