2010-03-23 44 views
20

在我們自己的喬恩斯基特的C# in depth,他討論了3種方式來模擬值類型一個「空」:如何在.net中引用可空類型?

  • 魔法值(例如最早可能日期時間被認爲是「空」)
  • 引用類型包裝器
  • 布爾標誌

要提及的是空類型使用第三種方法。引擎蓋下的可空類型究竟如何工作?

+4

無恥的插件:我寫了一篇關於它是如何工作的博客文章:http://softwareblog.alcedo.com/post/2010/02/16/Nullable3cT3e-vs-null.aspx – 2010-03-23 21:44:50

+0

@FredrikMörk鏈接不再可用... – 2017-02-06 10:09:48

+0

@ M.Mimpen現在它再次可用。前段時間,我的博客類似於我,但我已在其他地方重新發布,但是重定向了原始網址。 – 2017-02-25 10:11:42

回答

35

最終,它們只是一個帶有布爾標誌的通用結構 - 除了特殊的裝箱規則。由於結構是(默認)初始化爲零,則布爾默認爲false(沒有值):

public struct Nullable<T> where T : struct { 
    private readonly T value; 
    private readonly bool hasValue; 
    public Nullable(T value) { 
     this.value = value; 
     hasValue = true; 
    } 
    public T Value { 
     get { 
      if(!hasValue) throw some exception ;-p 
      return value; 
     } 
    } 
    public T GetValueOrDefault() { return value; } 
    public bool HasValue {get {return hasValue;}} 
    public static explicit operator T(Nullable<T> value) { 
     return value.Value; } 
    public static implicit operator Nullable<T>(T value) { 
     return new Nullable<T>(value); } 
} 

額外的差異,雖然:

  • 特殊的拳擊規則(不能正常做到這一點)
  • 特殊C#規則用於比較爲null等
  • 「解除」 在C#運營商(在.NET經由EqualityComparer<T>Comparer<T>等)
  • 上克特殊規則eneric類型約束(防止Nullable<Nullable<T>>
+1

拳擊如何處理?我能爲自己的結構實施自己的拳擊規則嗎? – 2010-03-23 21:45:14

+1

它由CLI中的特殊規則處理。不,你*不能*自己做這件事。同樣,「提升」的運營商也不是你自己能做的事情。 – 2010-03-23 21:46:22

+1

還值得注意的是,操作符的行爲是由語言控制的--C#和VB對這個操作符有不同的規則。 – 2010-03-23 23:31:13

4

Nullable<T>作品通過提供兩個字段:

private bool hasValue; 
internal T value; 

性質從這些工作。如果將其設置爲null,則hasValue設置爲false。

+0

但這不是簡單的可能,因爲'T'和'Nullable '都是結構體,結構體不能簡單地設置爲'null'。 – honzakuzel1989 2016-10-27 08:53:12