2015-06-22 17 views
18

Nessuno può far luce sul motivo per cui questo test dell'unità non funziona in Visual Studio 2013?Il compilatore C# sta ottimizzando i tipi nullable?

[TestMethod] 
public void Inconceivable() 
{ 
    int? x = 0; 
    Assert.AreEqual(typeof(int?), x.GetType()); 
} 
+0

Assert.IsInstanceOfType (? X, typeof (int)); –

+0

Perché stai cercando di affermare qualcosa che è statisticamente determinato dal compilatore? 'x' * non può * essere nulla oltre a un' int? 'o il programma non si compilerebbe. – Servy

+2

@Servy - Il mio punto era che il test dell'unità fallisce quando non dovrebbe. Discosultan ha fatto un ottimo lavoro nel spiegare perché. Lascio ai filosofi dibattere se GetType debba o meno comportarsi come fa. –

risposta

27

Il test sta fallendo perché:

Calling GetType su un tipo Nullable impedisce l'operazione di boxe per essere eseguita quando il tipo è implicitamente convertito in Object. Pertanto, GetType restituisce sempre un oggetto tipo che rappresenta il tipo sottostante, non il tipo Nullable.

È possibile leggere altro da How to: Identify a Nullable Type.

Alcuni esempi tratti dal precedente articolo:

int? i = 5; 
Type t = i.GetType(); 
Console.WriteLine(t.FullName); //"System.Int32" 

noti inoltre che:

L'operatore C# is opera anche sul tipo sottostante di un Nullable. Pertanto non è possibile utilizzare è per determinare se una variabile è un tipo Nullable. L'esempio seguente mostra che l'operatore è l'operatore tratta una variabile N <int> int come int.

int? i = 5; 
if (i is int) { ... } // true 

Lei ha ragione nel presumere che il compilatore C# è l'ottimizzazione tipi nullable. Ecco una citazione da Jon Skeet di C# in Depth che dovrebbe rispondere alla tua domanda:

E 'solo rispetto alla boxe e unboxing che il CLR ha alcun comportamento speciale per quanto riguarda i tipi nullable. In realtà, il comportamento è stato modificato solo poco prima del rilascio di .NET 2.0, come risultato delle richieste della comunità.

Un'istanza di Nullable è racchiusa in un riferimento null (se non ha un valore) o un valore in box di T (se lo fa). Non si limita mai a "intro nullable inscatolato", non esiste questo tipo.


C'è un filo simile su StackOverflow: Nullable type is not a nullable type?

+0

Questa è una discontinuità semantica, se io ' ne ho mai visto uno! –

Problemi correlati