Каковы были дизайнерские решения, которые приводили доводы в пользу того, что они void
не конструируемы и не допускаются в качестве универсального типа? В конце концов, это просто специальная пустая ячейка, struct
которая позволила бы избежать общего PITA, состоящего из отдельных участников Func
и Action
делегатов.
(C ++ допускает явные void
возвраты и допускает void
в качестве параметра шаблона)
c#
.net
language-design
Томас Оуэнс
источник
источник
Ответы:
Основная проблема с «void» заключается в том, что это не означает то же самое, что и любой другой тип возвращаемого значения. «void» означает «если этот метод возвращает, он не возвращает никакого значения». Ненулевой; ноль это значение. Он не возвращает никакого значения вообще.
Это действительно портит систему типов. Система типов - это, по сути, система для логических выводов о том, какие операции допустимы для определенных значений; метод возврата void не возвращает значение, поэтому вопрос "какие операции допустимы для этой вещи?" не имеет никакого смысла вообще. Там нет «вещи» для операции, действительной или недействительной.
Более того, это портит время выполнения чего-то жестокого. Среда выполнения .NET представляет собой реализацию виртуальной системы выполнения, которая указана как стековая машина. То есть виртуальная машина, где все операции характеризуются с точки зрения их влияния на стек оценки. (Конечно, на практике машина будет реализована на машине как со стеком, так и с регистрами, но виртуальная система исполнения предполагает только стек.) Эффект от вызова метода void принципиальноотличается от эффекта вызова не пустого метода; не пустые методы всегда помещают в стек что-то, что может потребоваться удалить. Метод void никогда не помещает что-либо в стек. И поэтому компилятор не может обрабатывать void и non-void методы одинаково в случае, когда возвращаемое значение метода игнорируется; если метод void, тогда возвращаемого значения нет, поэтому не должно быть pop.
По всем этим причинам «void» не является типом, который может быть создан; у него нет ценностей , вот и весь смысл. Он не может быть преобразован в объект, и метод возврата пустоты никогда не может быть обработан полиморфно с помощью метода, не возвращающего пустоту, поскольку это приводит к повреждению стека!
Таким образом, void не может быть использован в качестве аргумента типа, что является позором, как вы заметили. Это было бы очень удобно.
Оглядываясь назад, было бы лучше для всех заинтересованных сторон, если бы вместо ничего, метод, возвращающий пустоту, автоматически возвращал «Unit», магический одноэлементный эталонный тип. Тогда вы будете знать, что каждый вызов метода помещает что-то в стек , вы знаете, что каждый вызов метода возвращает что-то, что может быть присвоено переменной типа объекта , и, конечно, Unit может использоваться в качестве аргумента типа , так что будет нет необходимости иметь отдельные типы делегатов Action и Func. К сожалению, это не тот мир, в котором мы находимся.
Еще несколько мыслей в этом ключе смотрите:
источник
Void
должно быть в порядке, чтобы быть переданным как бесконечное количество аргументов внутри 0 стековых байтов. Когда любая структура нуждается в преобразованииobject
или вызове метода (для полученияthis
), она помещается в кучу соType
ссылкой, вставленной перед областью памяти (для многих реализаций CLR), и, таким образом, может обрабатываться надлежащим образом. Для меня тип - это просто группировка объектов, которые можно различить по некоторым характеристикам (полям).Void
это только один объект.void
это был пустой тип значения, то это утверждение могло бы привести к нулевым инструкциям машинного кода. Не очень полезно для жестко запрограммированного типаVoid
, но полезно в тех случаях, когда тип имеет несколько общих параметров, но некоторые не нужны в определенных случаях.От: http://connect.microsoft.com/VisualStudio/feedback/details/94226/allow-void-to-be-parameter-of-generic-class-if-not-in-c-then-just-in- время выполнения
Я не могу на всю жизнь понять, насколько пустота - дыра в безопасности, но ... так сказано.
источник