{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/",
  "atlas": "https://www.pystone.net/?node=csharp-nullable-types-null-operators#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/csharp-nullable-types-null-operators.md",
  "context": "https://www.pystone.net/notes/csharp-nullable-types-null-operators.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:csharp-nullable-types-null-operators",
  "slug": "csharp-nullable-types-null-operators",
  "title": "C#可空类型与空值运算符",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "C 可空类型与空值运算符",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "9eaf7d65e5b7f88e848237711243519514c50d8e0442d09f7fe35e56044d15ed",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "C#可空类型与空值运算符",
      "anchor": "c可空类型与空值运算符",
      "citation": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/#c%E5%8F%AF%E7%A9%BA%E7%B1%BB%E5%9E%8B%E4%B8%8E%E7%A9%BA%E5%80%BC%E8%BF%90%E7%AE%97%E7%AC%A6"
    },
    {
      "depth": 2,
      "text": "可空类型修饰符(?)",
      "anchor": "可空类型修饰符",
      "citation": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/#%E5%8F%AF%E7%A9%BA%E7%B1%BB%E5%9E%8B%E4%BF%AE%E9%A5%B0%E7%AC%A6"
    },
    {
      "depth": 4,
      "text": "System.Nullable variable",
      "anchor": "systemnullable-variable",
      "citation": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/#systemnullable-variable"
    },
    {
      "depth": 4,
      "text": "T? variable",
      "anchor": "t-variable",
      "citation": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/#t-variable"
    },
    {
      "depth": 2,
      "text": "三元(运算符)表达式(?:)",
      "anchor": "三元运算符表达式",
      "citation": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/#%E4%B8%89%E5%85%83%E8%BF%90%E7%AE%97%E7%AC%A6%E8%A1%A8%E8%BE%BE%E5%BC%8F"
    },
    {
      "depth": 2,
      "text": "空合并运算符(??)",
      "anchor": "空合并运算符",
      "citation": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/#%E7%A9%BA%E5%90%88%E5%B9%B6%E8%BF%90%E7%AE%97%E7%AC%A6"
    },
    {
      "depth": 2,
      "text": "NULL检查运算符（?.）",
      "anchor": "null检查运算符",
      "citation": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/#null%E6%A3%80%E6%9F%A5%E8%BF%90%E7%AE%97%E7%AC%A6"
    },
    {
      "depth": 2,
      "text": "(?[])运算符：",
      "anchor": "运算符",
      "citation": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/#%E8%BF%90%E7%AE%97%E7%AC%A6"
    },
    {
      "depth": 2,
      "text": "语法糖",
      "anchor": "语法糖",
      "citation": "https://www.pystone.net/notes/csharp-nullable-types-null-operators/#%E8%AF%AD%E6%B3%95%E7%B3%96"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:programming-languages-and-runtimes",
      "title": "编程语言与运行时",
      "url": "https://www.pystone.net/notes/programming-languages-and-runtimes/",
      "atlas": "https://www.pystone.net/?node=programming-languages-and-runtimes#knowledge-atlas",
      "label": "编程语言与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": ".NET与CSharp中的“C#可空类型与空值运算符”导航项",
      "citation": "https://www.pystone.net/notes/programming-languages-and-runtimes/#net%E4%B8%8Ecsharp"
    }
  ],
  "contentMarkdown": "# C#可空类型与空值运算符\n\n> 创建时间：2020/5/20 17:10\n\n参考：<https://blog.csdn.net/qq_42453390/article/details/90403344>\n\n## 可空类型修饰符(?)\n\n引用类型可以使用空引用表示一个不存在的值，而值类型通常不能表示为空。\n例如：string str=null; 是正确的，int i=null; 编译器就会报错。\n为了使值类型也可为空，就可以使用可空类型\n\n#### System.Nullable variable\n\n#### T? variable\n\nT? 其实是System.Nullable(泛型结构）的缩写形式，也就意味着当你用到T?时编译器编译时会把T？编译成System.Nullable的形式。\nT 可以是包括 struct 在内的任何值类型，但不能是引用类型\nT? 意思就是 T范围值+ 上可为空的值\n**可以为 null 的类型的每个实例都具有两个公共的只读属性：**\n**HasValue** ： bool 类型。 当变量包含非 null 值时，它被设置为 true。\n**Value** ：Value 的类型与基础类型相同。 如果 HasValue 为 true，则说明 Value 包含有意义的值。 如果 HasValue 为 false，则访问 Value 将引发 InvalidOperationException异常。\n\n> 值类型和引用类型\n>  bool, string, int 这些叫做值类型（value type)；\n>  Boolean, String, Int32这些叫做引用类型（Reference Type）。\n>  值类型存在内存的 **stack（堆栈）** 中。\n>  引用类型存在 **heap（堆）** 中。\n\n## 三元(运算符)表达式(?:)\n\nx?y:z\n\n```csharp\nstring str1 = String.Empty;\nstring str2 = String.Empty;\n\nstr2 = String.Intern(sb.ToString());\n\nif((object)str1==(object)str2)\n    Console.WriteLine(&quot;The strings are equal.&quot;);\nelse\n    Console.WriteLine(&quot;The strings are not equal.&quot;);\n\n```\n\n## 空合并运算符(??)\n\n用于定义可空类型和引用类型的默认值。\n如果此运算符的左操作数不为null，则此运算符将返回左操作数，否则返回右操作数。\n例如：a??b 当a为null时则返回b，a不为null时则返回a本身。\n\n> 空合并运算符为右结合运算符，即操作时从右向左进行组合的。\n>  如，“a??b??c”的形式按“a??(b??c)”计算。\n\n## NULL检查运算符（?.）\n\n若要获取一个Point序列的第一个点的X坐标：\nint firstX = points.First().X;\n但是，老鸟会告诉你， **这儿没有进行NULL检查** ，正确的版本是这样的：\n\n```csharp\nstring str1 = String.Empty;\nstring str2 = String.Empty;\n\nstr2 = String.Intern(sb.ToString());\n\nif((object)str1==(object)str2)\n    Console.WriteLine(&quot;The strings are equal.&quot;);\nelse\n    Console.WriteLine(&quot;The strings are not equal.&quot;);\n\n```\n\n这样写正确，但代码取变得难读多了。\n在C# 6.0中，引入了一个 ?. 的运算符，前面的代码可以改成如下形式：\n`int? firstX = points?.FirstOrDefault()?.X;`\n如果对象为NULL，则不进行后面的获取成员的运算，直接返回NULL\n\n需要注意的是，由于”?.“运算符返回的可以是NULL，当返回的成员类型是struct类型的时候，”?.“和”.”运算符的返回值类型是不一样的。\nPoint p = new Point(3, 2);\nConsole.WriteLine(p.X.GetType() == typeof(int)); //true\nConsole.WriteLine(p?.X.GetType() == typeof(int?)); //true\n\n## (?[])运算符：\n\nint? first = customers?[0].Orders.Count();\n\n## 语法糖\n\n本质：都使用了语法糖，在编译阶段编译器会把特殊符号先转译成原始状态再编译。\n\n> 参考：<https://www.jianshu.com/p/96526064ed38>\n>  **语法糖(Syntactic sugar)** ，也译为 **糖衣语法** ，是由英国计算机科学家彼得·约翰·兰达（Peter J. Landin）发明的一个术语，指计算机语言中添加的某种语法，这种语法对语言的功能并没有影响，但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性，从而减少程序代码出错的机会。需要声明的是“语法糖”这个词绝非贬义词，它可以给我们带来方便，是一种便捷的写法，编译器会帮我们做转换；而且可以提高开发编码的效率，在性能上也不会带来损失。\n"
}
