小知识:.Net中?和??的含义

来源:互联网 发布:浙江大学网络教育证书 编辑:程序博客网 时间:2024/05/01 14:12
      int? demo = null;          // int?的含义是什么
      int result = demo ?? -5;   // ??的含义是什么
      result = (int)(result + demo);
      Console.WriteLine(result);


T? 表示 System.Nullable<T>,int ?表示System.Nullable<int>;

“demo ?? -5” 表示在demo为null时返回-5

下面引用自MSDN:

对于System.Nullable泛型结构,表示基础类型为值类型的对象,值类型与引用类型一样也可以分配 空引用(在 Visual Basic 中为 Nothing)。

对于一个类型,如果既可以给它分配一个值,也可以给它分配 空引用(在 Visual Basic 中为 Nothing)(表示没有任何值),我们就说这个类型是可空的。因此,可空类型可表示一个值,或表示不存在任何值。例如,类似 String 的引用类型就是可空类型,而类似 Int32 的值类型不是可空类型。由于值类型的容量只够表示适合于该类型的值,因此它不可为空;值类型没有表示空值所需的额外容量。

Nullable 结构支持只将一个值类型用作可空类型,因为引用类型本身就是可空的。

Nullable 类为 Nullable 结构提供补充支持。Nullable 类支持获取可空类型的基础类型,以及对基础值类型不支持一般的比较和相等性操作的可空类型进行成对的比较和相等性操作。

方案

根据不同的应用场合,可使用可空类型来表示存在或不存在的内容。例如,HTML 标记的某个可选属性可能存在于某一个标记中,但不存在于另一个标记中;或者数据库表的某个可空列可能存在于表的某一行中,但不存在于另一行中。

可将属性或列表示为类中的字段,并且可将该字段定义为值类型。该字段可包含属性或列的所有有效值,但不能提供一个附加值来表示属性或列不存在。在这种情况下,应将该字段定义为可空类型,而不是值类型。

基本属性

Nullable 结构的两个基础成员为 HasValue 和 Value 属性。如果 Nullable 对象的 HasValue 属性为 true,则可以使用 Value 属性访问该对象的值。如果 HasValue 属性为 false,则表示尚未定义该对象的值,并且尝试访问 Value 属性时会引发 InvalidOperationException。

装箱和取消装箱

在对可空类型进行装箱时,公共语言运行库自动将 Nullable 对象的基础值(而不是 Nullable 对象本身)装箱。也就是说,如果 HasValue 属性为 true,则将 Value 属性的内容装箱。如果 HasValue 属性为 false,则将空引用(在 Visual Basic 中为 Nothing)装箱。在对可空类型的基础值进行取消装箱时,公共语言运行库创建一个新的初始化为基础值的 Nullable 结构。

// This code example demonstrates the Nullable<T> class.// The code example defines a database table in which two columns // are nullable. In the application, an array of rows is created // and initialized. The table rows could subsequently be // written to a database.using System;class Sample {// Define the "titleAuthor" table of the Microsoft "pubs" database.     public struct titleAuthor     {    // Author ID; format ###-##-####    public string au_id;    // Title ID; format AA####    public string title_id;    // Author ORD is nullable.    public short? au_ord;    // Royalty Percent is nullable.    public int? royaltyper;    }    public static void Main()     {// Declare and initialize the titleAuthor array.    titleAuthor[] ta = new titleAuthor[3];    ta[0].au_id = "712-32-1176";    ta[0].title_id = "PS3333";    ta[0].au_ord = 1;    ta[0].royaltyper = 100;      ta[1].au_id = "213-46-8915";    ta[1].title_id = "BU1032";    ta[1].au_ord = null;    ta[1].royaltyper = null;    ta[2].au_id = "672-71-3249";    ta[2].title_id = "TC7777";    ta[2].au_ord = null;    ta[2].royaltyper = 40;// Display the values of the titleAuthor array elements, and // display a legend.    Display("Title Authors Table", ta);    Console.WriteLine("Legend:");    Console.WriteLine("An Author ORD of -1 means no value is defined.");    Console.WriteLine("A Royalty % of 0 means no value is defined.");    }// Display the values of the titleAuthor array elements.    public static void Display(string dspTitle,                                titleAuthor[] dspAllTitleAuthors)    {    Console.WriteLine("*** {0} ***", dspTitle);    foreach (titleAuthor dspTA in dspAllTitleAuthors)       {       Console.WriteLine("Author ID ... {0}", dspTA.au_id);       Console.WriteLine("Title ID .... {0}", dspTA.title_id);       Console.WriteLine("Author ORD .. {0}", dspTA.au_ord ?? -1);       Console.WriteLine("Royalty % ... {0}", dspTA.royaltyper ?? 0);       Console.WriteLine();              }    }}/*This code example produces the following results:*** Title Authors Table ***Author ID ... 712-32-1176Title ID .... PS3333Author ORD .. 1Royalty % ... 100Author ID ... 213-46-8915Title ID .... BU1032Author ORD .. -1Royalty % ... 0Author ID ... 672-71-3249Title ID .... TC7777Author ORD .. -1Royalty % ... 40Legend:An Author ORD of -1 means no value is defined.A Royalty % of 0 means no value is defined.*/