2015-06-22 15 views
18

Kann jemand Licht in den Grund dafür bringen, warum dieser Komponententest in Visual Studio 2013 fehlschlägt?Optimiert der C# -Compiler NULL-Typen?

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

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

+0

Warum versuchen Sie etwas zu behaupten, das vom Compiler statisch bestimmt wird? 'x' * kann * nichts anderes sein als ein' int? 'oder das Programm kompiliert nicht. – Servy

+2

@Servy - Mein Punkt war, dass der Komponententest fehlschlägt, wenn es nicht sollte. Discosultan hat hervorragend erklärt, warum. Ich überlasse es den Philosophen zu diskutieren, ob sich GetType so verhalten soll oder nicht. –

Antwort

27

Ihr Test versagt, weil:

GetType auf einem Nullable Typ Aufruf bewirkt, dass eine Box-Operation durchgeführt werden, wenn der Typ implizit in Object umgewandelt wird. Daher GetType gibt immer ein Typ Objekt zurück, das den zugrunde liegenden Typ darstellt, nicht den Nurable-Typ.

Sie können mehr von How to: Identify a Nullable Type lesen.

Einige Beispiele aus dem vorherigen Artikel entnommen:

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

Auch beachten:

Der C# is Operator auf einen zugrunde liegenden Typ des Nullable betreibt. Daher können Sie nicht verwenden, um zu bestimmen, ob eine Variable ein Nurable-Typ ist. Das folgende Beispiel zeigt, dass der Operator eine Nullable <int> Variable als int behandelt.

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

Sie sind richtig in der Annahme, dass der C# -Compiler Nullable Types optimiert. Hier ist ein Zitat von Jon Skeet C# in Depth, die Frage zu beantworten:

Es ist nur in Bezug auf Boxen und Unboxing, dass die CLR hat irgendein spezielles Verhalten in Bezug auf Nullable Types. Tatsächlich wurde das Verhalten erst kurz vor der Veröffentlichung von .NET 2.0 als Folge von Community-Anfragen geändert.

Eine Instanz von Nullable ist entweder mit einer Nullreferenz (wenn sie keinen Wert hat) oder mit einem Boxwert von T (falls dies der Fall ist) eingerahmt. Es wird nie zu einem "boxed nullable int" gepackt - es gibt keinen solchen Typ.


Es gibt einen ähnlichen Thread auf Stackoverflow: Nullable type is not a nullable type?

+0

Das ist eine semantische Diskontinuität, wenn ich ' habe schon mal einen gesehen! –