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