Принципова проблема "пустоти" полягає в тому, що це не означає те саме, що і будь-який інший тип повернення. "void" означає "якщо цей метод повертається, то він взагалі не повертає значення". Не нульовий; null - значення. Він не повертає жодного значення.
Це дійсно заплутує систему типів. Система типу по суті є системою для здійснення логічних відрахувань щодо того, які операції є дійсними для певних значень; метод повернення недійсності не повертає значення, тому питання "які операції дійсні над цією річчю?" взагалі не має сенсу. Немає жодної "речі", щоб не було операції, дійсної чи недійсної.
Більше того, це псує час виконання щось жорстоке. Виконання .NET - це реалізація віртуальної системи виконання, яка задається як стек-машина. Тобто віртуальна машина, де всі операції характеризуються з точки зору їх впливу на стек оцінки. (Звичайно, на практиці машина буде реалізована на машині як з стеком, так і з регістрами, але система віртуальної роботи передбачає лише стек.) Ефект виклику недійсного методу принципововідрізняється від ефекту виклику недійсного методу; недійсний метод завжди ставить щось на стек, що може знадобитися вискочити. Недійсний метод ніколи не ставить щось на стек. Отже, компілятор не може ставитись до недійсних та недійсних методів однаково у випадку, коли повернене значення методу ігнорується; якщо метод недійсний, то значення повернення немає, тому поп не повинен бути.
З усіх цих причин "недійсність" не є типом, який може бути ініційований; у неї немає значень , у цьому вся суть. Це не конвертоване в об'єкт, і метод повернення порожнеч ніколи не може бути поліморфно оброблений методом, який не повертає недійсність, тому що це пошкоджує стек!
Таким чином, void не може використовуватися як аргумент типу, що шкода, як ви зазначаєте. Було б дуже зручно.
З користю заднього огляду, всім зацікавленим було б краще, якби замість нічого іншого, метод, що повертає недійсність, автоматично повертав "Одиницю", магічний одинарний посилання типу. Тоді ви б знали, що кожен виклик методу ставить щось на стек , ви знаєте, що кожен виклик методу повертає щось, що може бути призначено змінній типу об'єкта , і, звичайно, Unit може використовуватися як аргумент типу , так що не потрібно мати окремих типів делегування Action та Func. На жаль, ми не в світі.
Щоб дізнатися більше про цю думку, див: