2011-04-09 161 views
13

我很想知道Nullable類型是如何在幕後工作的。它是否創建了一個新的對象(對象可以被賦值爲null)並且可能的值爲null?Nullable <T>類型如何在幕後工作?

在這個例子中,我們使用一個可爲空的<int>,是否將它們從某個對象隱式轉換爲一個int,反之亦然?

另外我知道如何手動創建,是否有使用Nullable類型而不是自己創建它的良性?

+0

@Rfvgyhn我實在不明白這是怎麼重複。他們想知道一個int和一個可爲空的之間的區別。這不是我問的。 – loyalpenguin 2011-04-09 04:09:38

+0

這是110229的重複! – 2011-04-09 05:32:46

+0

@Frank如何而不是試圖結束我的問題,你發佈一個答案,以幫助我和社區。顯然這裏有答案在你提到的問題中沒有提到或解釋過。也是第二次他們不問我要求什麼。 – loyalpenguin 2011-04-09 05:38:53

回答

11

可空類型是一個由兩個字段組成的結構:一個bool和一個T。當值爲null時,布爾值爲false,並且T具有默認值。當值不爲null時,布爾值爲true。

與自己實現功能相比,使用Nullable有兩大好處。有ChaosPandion的答案中詳細描述的語言支持,並且事實上裝箱(轉換爲object)將自動刪除可空的「包裝器」,從而留下空引用或純T對象.z

+0

+1爲偉大的解釋。你有沒有這方面的參考,我可以更詳細地看看它? – loyalpenguin 2011-04-09 04:12:09

+3

具體在哪方面? http://msdn.microsoft.com/en-us/library/ms228597.aspx解釋拳擊的事情。 – Random832 2011-04-09 04:27:43

+0

是的,你去了。謝謝。 – loyalpenguin 2011-04-09 04:32:19

1

Nullable<T>被實現爲覆蓋Equals()表現爲null如果HasValuefalse一個結構。有一個從TT?的隱式轉換,以及如果!HasValue在另一方向上的明確轉換。

8

其實很簡單。編譯器爲您提供了語法。

// this 
int? x = null; 
// Transformed to this 
int? x = new Nullable<int>() 

// this 
if (x == null) return; 
// Transformed to this 
if (!x.HasValue) return; 

// this 
if (x == 2) return; 
// Transformed to this 
if (x.GetValueOrDefault() == 2 && x.HasValue) return; 
+0

你能證實(反射器)這是真的嗎?最後,最後一行不應該是必須的,因爲隱式操作符Nullable (參見[@ barrylloyd's answer](http://stackoverflow.com/questions/5602773/how-does-a-nullablet -type-work-behind-the-scenes/5602820#5602820)) – 2011-04-09 04:16:10

+0

我在linqpad中運行了這個程序並確認最後一行包含對這兩個屬性的調用。這是關於==本身如何實現的,即使有另一個可爲空。 'if(x == y)'變成'if(x.GetValueOrDefault()== y.GetValueOrDefault()&& x.HasValue == y.HasValue)'。 – Random832 2011-04-09 04:31:44

+0

@BlueRaja - Danny Pflughoeft - 發生了什麼事情。 – ChaosPandion 2011-04-09 04:34:05

10

下面是對可空運行.NET反射器(收拾)代碼...

[Serializable, StructLayout(LayoutKind.Sequential), TypeDependency("System.Collections.Generic.NullableComparer`1"), TypeDependency("System.Collections.Generic.NullableEqualityComparer`1")] 
public struct Nullable<T> where T: struct 
{ 

private bool hasValue; 
internal T value; 

public Nullable(T value) 
{ 
    this.value = value; 
    this.hasValue = true; 
} 

public bool HasValue 
{ 
    get 
    { 
     return this.hasValue; 
    } 
} 

public T Value 
{ 
    get 
    { 
     if (!this.HasValue) 
     { 
      ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue); 
     } 
     return this.value; 
    } 
} 

public T GetValueOrDefault() 
{ 
    return this.value; 
} 

public T GetValueOrDefault(T defaultValue) 
{ 
    if (!this.HasValue) 
    { 
     return defaultValue; 
    } 
    return this.value; 
} 

public override bool Equals(object other) 
{ 
    if (!this.HasValue) 
    { 
     return (other == null); 
    } 
    if (other == null) 
    { 
     return false; 
    } 
    return this.value.Equals(other); 
} 

public override int GetHashCode() 
{ 
    if (!this.HasValue) 
    { 
     return 0; 
    } 
    return this.value.GetHashCode(); 
} 

public override string ToString() 
{ 
    if (!this.HasValue) 
    { 
     return ""; 
    } 
    return this.value.ToString(); 
} 

public static implicit operator Nullable<T>(T value) 
{ 
    return new Nullable<T>(value); 
} 

public static explicit operator T(Nullable<T> value) 
{ 
    return value.Value; 
} 
} 
+0

這是嗎? 'hasValue'設置在哪裏? – 2011-04-09 04:19:27

+2

hasValue默認爲False,只在構造函數中設置爲True – barrylloyd 2011-04-09 04:31:55

+0

啊,我知道它是不可變的。不知道我在想什麼...謝謝! – 2011-04-09 05:02:58

相關問題