El problema fundamental con "void" es que no significa lo mismo que cualquier otro tipo de devolución. "void" significa "si este método devuelve, entonces no devuelve ningún valor". No nulo; nulo es un valor. No devuelve ningún valor en absoluto.
Esto realmente desordena el sistema de tipos. Un sistema de tipos es esencialmente un sistema para hacer deducciones lógicas sobre qué operaciones son válidas en valores particulares; un método de devolución no válido no devuelve un valor, por lo que la pregunta "¿qué operaciones son válidas en esto?" no tiene ningún sentido en absoluto No hay ninguna "cosa" para que haya una operación, válida o no válida.
Por otra parte, esto confunde el tiempo de ejecución algo feroz. El tiempo de ejecución de .NET es una implementación del Sistema de ejecución virtual, que se especifica como una máquina de pila. Es decir, una máquina virtual donde todas las operaciones se caracterizan en términos de su efecto en una pila de evaluación. (Por supuesto, en la práctica, la máquina se implementará en una máquina con pila y registros, pero el sistema de ejecución virtual solo asume una pila). El efecto de una llamada a un método de anulación es fundamentalmente diferente de el efecto de una llamada a un método no nulo; un método no vacío siempre pone algo en la pila, que puede ser necesario quitar. Un método vacío nunca pone algo en la pila. Y, por lo tanto, el compilador no puede tratar los métodos void y non-void de la misma manera en el caso de que se ignore el valor devuelto del método; si el método es nulo, entonces no hay un valor de retorno, por lo que no debe haber pop.
Por todas estas razones, "void" no es un tipo que pueda ser instanciado; no tiene ningún valor , ese es su punto. No es convertible en objeto, y un método de devolución de vacío nunca puede ser tratado de manera polimórfica con un método de devolución de vacío porque esto corrompe la pila.
Por lo tanto, void no se puede usar como un argumento de tipo, lo que es una vergüenza, como se nota. Sería muy conveniente.
Con el beneficio de la visión retrospectiva, hubiera sido mejor para todos los interesados si, en lugar de nada, un método de devolución de vacíos devolviera automáticamente "Unidad", un tipo de referencia mágico de singleton. Entonces sabría que cada llamada de método pone algo en la pila , sabría que cada llamada de método devuelve algo que podría asignarse a una variable de tipo de objeto , y de Por supuesto, la unidad se puede usar como un argumento de tipo , por lo que no sería necesario tener tipos de delegado de Action y Func separados. Lamentablemente, ese no es el mundo en el que estamos.
Para más pensamientos en este sentido, vea: