Perché 'void' non è consentito come tipo generico in C #

52

Quali sono state le decisioni di progettazione che hanno sostenuto a favore di void di non essere costruibili e non consentite come tipo generico? Dopotutto è solo uno speciale% vuoto% co_de e avremmo evitato il totale PITA di avere delegato struct e Func delegati.

(C ++ consente espliciti ritorni di Action e consente void come parametro del modello)

    
posta Thomas Owens 20.01.2012 - 14:44
fonte

2 risposte

67

Il problema fondamentale con "void" è che non significa la stessa cosa di qualsiasi altro tipo di ritorno. "void" significa "se questo metodo restituisce, non restituisce alcun valore". Non nullo; null è un valore. Non restituisce alcun valore.

Questo rovina davvero il sistema dei tipi. Un sistema di tipi è essenzialmente un sistema per fare deduzioni logiche su quali operazioni sono valide su valori particolari; un metodo di restituzione void non restituisce un valore, quindi la domanda "quali operazioni sono valide su questa cosa?" non ha alcun senso. Non c'è "cosa" per cui ci sia un'operazione, valida o non valida.

Inoltre, questo mette a dura prova il runtime. Il runtime .NET è un'implementazione del Virtual Execution System, che viene specificato come stack machine. Cioè, una macchina virtuale in cui le operazioni sono tutte caratterizzate in termini del loro effetto su uno stack di valutazione. (Ovviamente nella pratica la macchina verrà implementata su una macchina con stack e registri, ma il sistema di esecuzione virtuale assume solo uno stack.) L'effetto di una chiamata a un metodo di annullamento è fondamentalmente diverso da l'effetto di una chiamata a un metodo non vuoto; un metodo non vuoto mette sempre qualcosa in pila, che potrebbe dover essere saltato fuori. Un metodo vuoto non mette mai in pila qualcosa. E quindi il compilatore non può trattare i metodi void e non-vuoto lo stesso nel caso in cui il valore restituito dal metodo sia ignorato; se il metodo è vuoto allora non c'è alcun valore di ritorno quindi non ci deve essere pop.

Per tutti questi motivi, "void" non è un tipo che può essere istanziato; ha nessun valore , questo è il suo intero punto. Non è convertibile in oggetto, e un metodo di restituzione del vuoto non può mai, mai essere trattato polimorficamente con un metodo di restituzione non vuoto perché così facendo corrompe lo stack!

Quindi, void non può essere usato come argomento di tipo, il che è un vero peccato, come si nota. Sarebbe molto conveniente.

Con il senno di poi, sarebbe stato meglio per tutti gli interessati se invece di nulla, un metodo di ritorno vuoto restituiva automaticamente "Unità", un magico tipo di riferimento singleton. Sapresti allora che ogni chiamata al metodo mette qualcosa nello stack , sapresti che ogni chiamata al metodo restituisce qualcosa che potrebbe essere assegnato a una variabile di tipo oggetto e di corso L'unità potrebbe essere utilizzata come argomento di tipo , quindi non sarebbe necessario disporre di tipi di delegati Action e Func distinti. Purtroppo, non è il mondo in cui ci troviamo.

Per ulteriori riflessioni in questo filone vedi:

risposta data 20.01.2012 - 20:48
fonte
9

Da: link

This is actually by design - we don't allow any instance of the void type (along with many other types in the runtime). You can't CreateInstance a void or void[] either. We plugged these type holes for security.

Non posso per la vita di me vedere quanto vuoto sia un buco di sicurezza, ma ... come dice.

    
risposta data 20.01.2012 - 16:51
fonte

Leggi altre domande sui tag