2015-07-24 20 views
7

Come tutti sapete, in C# non siamo riusciti a fare qualcosa di simile:Ho istanziato un oggetto di vuoto?

var voidObject = new void(); 

o

var voidObject = new System.Void(); 

o

var voidObject = Activator.CreateInstance(typeof(void)); 

Ma questo codice viene compilato con successo e in modalità debug I può vedere che il tipo di voidObject è System.Void:

var voidObject = FormatterServices.GetUninitializedObject(typeof(void)); 

Che cos'è questo? Questa è l'istanza reale di void?

+1

Wow ... Totalmente inutile ma incredibile :-) Hanno dimenticato di chiudere quel percorso :-) – xanatos

+0

Ho ottenuto questo 'Espressione è stata valutata e non ha valore' –

+0

Su .NET https://dotnetfiddle.net/BUUdKU e su Mono https://ideone.com/LegWvM – xanatos

risposta

3

Da quello che posso vedere che è un buon perfettamente, perfettamente valido inscatolatoSystem.Void tipo di valore :-)

Puoi

Console.WriteLine(voidObject.GetType()); 

e vedere che si tratta di un System.Void.

System.Void è un tipo di valore, in modo da creare attraverso FormatterServices.GetUninitializedObject dovrebbe essere uguale a fare (object)default(void) (perché FormatterServices.GetUninitializedObject restituirà un tipo di valore con tutti i suoi campi impostati al loro valore di default) (nota che chiaramente (object)default(void) è illegale).

Ancora non ci sono molte cose che potete fare con il vostro boxedSystem.Void ...

var voidObject = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(void)); 
var voidObject2 = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(typeof(void)); 

Console.WriteLine("Type: {0}", voidObject.GetType()); 
Console.WriteLine("IsValueType: {0}", voidObject.GetType().IsValueType); 

Console.WriteLine("Equals: {0}", voidObject.Equals(voidObject2)); 
Console.WriteLine("GetHashCode1: {0}", voidObject.GetHashCode()); 
Console.WriteLine("GetHashCode2: {0}", voidObject2.GetHashCode()); 
Console.WriteLine("ToString: {0}", voidObject.ToString()); 

Sembra che ci sia alcune differenze tra .NET e Mono implementazioni ... On.NET tutte le istanze di System.Void hanno lo stesso GetHashCode(), mentre su Mono ognuna di esse ha un diverso GetHashCode(). Il Equals funziona correttamente (true) per entrambi.

(si noti che la differenza di GetHashCode() sembra essere un bug di Mono, con struct s senza campi: https://ideone.com/t0t8I6 che should be fixed nelle versioni più recenti)

0

Bene, Imstance è la parola da mille soldi che immagino. Se si crea un oggetto usando GetUninitializedObject si ottiene un oggetto unitializzato come menzionato il nome dei metodi rom. Supponiamo quindi di avere una classe Foo con alcuni membri nessuno di questi membri avrebbe alcun valore perché il costruttore non viene chiamato. Mentre lo Void non ha nemmeno un costruttore, non è possibile chiamare Activator.CreateInstance o utilizzare new void(). Comunque con l'approccio citato che non usa alcun costruttore tu ne crei un oggetto ma lo lasci unitializzato. Quindi questo è solo un caso speciale di lasciare un nuovo oggetto unitializzato.

Se si tratta di un bug, una funzionalità o qualsiasi altra cosa posso solo indovinare.

EDIT: E'obviosuly una caratteristica, il seguente da MSDN mi permette presumo così:

L'attuale metodo deve essere utilizzato solo per la deserializzazione quando l'utente intende compilare immediatamente tutti i campi. (https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject%28v=vs.110%29.aspx)

Così mentre è possibile creare un'istanza utilizzando questo metodo, è necessario farlo solo quando si forniscono tutte le informazioni necessarie immediatamente dopo la chiamata. Tuttavia, per cui lo void non ha alcun membro, il suo stato non è ancora valido.

Problemi correlati