{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/csharp-generic-where-constraint/",
  "atlas": "https://www.pystone.net/?node=csharp-generic-where-constraint#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/csharp-generic-where-constraint.md",
  "context": "https://www.pystone.net/notes/csharp-generic-where-constraint.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:csharp-generic-where-constraint",
  "slug": "csharp-generic-where-constraint",
  "title": "C# where泛型约束",
  "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 where泛型约束",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "03a4a0f38c90da108e7b7f124d36fe0fa8937d1031600980a4cf35321aa520dd",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "C# where泛型约束",
      "anchor": "c-where泛型约束",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#c-where%E6%B3%9B%E5%9E%8B%E7%BA%A6%E6%9D%9F"
    },
    {
      "depth": 2,
      "text": "where泛型类型约束",
      "anchor": "where泛型类型约束",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#where%E6%B3%9B%E5%9E%8B%E7%B1%BB%E5%9E%8B%E7%BA%A6%E6%9D%9F"
    },
    {
      "depth": 3,
      "text": "约束类型：",
      "anchor": "约束类型",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#%E7%BA%A6%E6%9D%9F%E7%B1%BB%E5%9E%8B"
    },
    {
      "depth": 4,
      "text": "接口约束",
      "anchor": "接口约束",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#%E6%8E%A5%E5%8F%A3%E7%BA%A6%E6%9D%9F"
    },
    {
      "depth": 4,
      "text": "基类约束",
      "anchor": "基类约束",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#%E5%9F%BA%E7%B1%BB%E7%BA%A6%E6%9D%9F"
    },
    {
      "depth": 4,
      "text": "class和struct约束",
      "anchor": "class和struct约束",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#class%E5%92%8Cstruct%E7%BA%A6%E6%9D%9F"
    },
    {
      "depth": 4,
      "text": "notnull 约束",
      "anchor": "notnull-约束",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#notnull-%E7%BA%A6%E6%9D%9F"
    },
    {
      "depth": 4,
      "text": "unmanaged 约束",
      "anchor": "unmanaged-约束",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#unmanaged-%E7%BA%A6%E6%9D%9F"
    },
    {
      "depth": 4,
      "text": "构造函数约束new()",
      "anchor": "构造函数约束new",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E7%BA%A6%E6%9D%9Fnew"
    },
    {
      "depth": 2,
      "text": "where子句",
      "anchor": "where子句",
      "citation": "https://www.pystone.net/notes/csharp-generic-where-constraint/#where%E5%AD%90%E5%8F%A5"
    }
  ],
  "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# where泛型约束”导航项",
      "citation": "https://www.pystone.net/notes/programming-languages-and-runtimes/#net%E4%B8%8Ecsharp"
    }
  ],
  "contentMarkdown": "# C# where泛型约束\n\n> 创建时间：2020/5/20 17:55\n\n## where泛型类型约束\n\n泛型定义中的 where 子句指定对用作 _泛型类型、方法、委托或本地函数_ 中 **类型参数** 的 **参数类型** 的约束。\n约束可指定接口、基类或要求泛型类型为引用、值或非托管类型。\n\n### 约束类型：\n\n#### 接口约束\n\n```xml\npublic class AGenericClass&lt;T&gt; where T : IComparable&lt;T&gt; { }\n\n```\n\n#### 基类约束\n\n表明用作该泛型类型的类型参数的类型具有指定的类作为基类（或者是该基类）。\n\n> 基类约束一经使用，就必须出现在该类型参数的所有其他约束之前。 某些类型不允许作为基类约束：Object、Array 和 ValueType。 在 C# 7.3 之前，Enum、Delegate 和 MulticastDelegate 也不允许作为基类约束。\n>  在 C# 8.0 及更高版本中的可为 null 上下文中，强制执行基类类型的为 null 性。 如果基类不可为 null（例如 Base），则类型参数必须不可为 null。 如果基类可为 null（例如 Base?），则类型参数可以是可为 null 或不可为 null 的引用类型。 当基类不可为 null 时，如果类型参数是可为 null 的引用类型，编译器将发出警告。\n\n```xml\npublic class UsingEnum&lt;T&gt; where T : System.Enum { }\npublic class UsingDelegate&lt;T&gt; where T : System.Delegate { }\npublic class Multicaster&lt;T&gt; where T : System.MulticastDelegate { }\n\n```\n\n#### class和struct约束\n\n> class 约束要求类型是不可为 null 的引用类型。 若要允许可为 null 的引用类型，请使用 class? 约束，该约束允许可为 null 和不可为 null 的引用类型。\n\n```csharp\nclass MyClass&lt;T, U&gt;\n    where T : class\n    where U : struct\n{ }\n\n```\n\n#### notnull 约束\n\n将类型参数限制为不可为 null 的类型。 该类型可以是值类型，也可以是不可为 null 的引用类型\n\n> 与其他约束不同，如果类型参数违反 notnull 约束，编译器会生成警告而不是错误。 警告仅在 nullable enable 上下文中生成。\n>  **重要** ：包含 notnull 约束的泛型声明可以在可为 null 的不明显上下文中使用，但编译器不会强制执行约束。\n\n```csharp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n#### unmanaged 约束\n\nunmanaged 约束将类型参数限制为名为“非托管类型”的类型。 使得在 C# 中编写低级别的互操作代码变得更容易。 此约束支持跨所有非托管类型的可重用例程。 unmanaged 约束不能与 class 或 struct 约束结合使用。 unmanaged 约束强制该类型必须为 struct：\n\n```csharp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n#### 构造函数约束new()\n\n让编译器知道：提供的任何类型参数都必须具有可访问的无参数构造函数。\n\n```csharp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n> 出现在 where 子句的最后。 new() 约束不能与 struct 或 unmanaged 约束结合使用。\n\n## where子句\n\n用在查询表达式中，用于指定将在查询表达式中返回数据源中的哪些元素。 它将一个布尔条件（谓词 ）应用于每个源元素（由范围变量引用），并返回满足指定条件的元素。 一个查询表达式可以包含多个 where 子句，一个子句可以包含多个谓词子表达式。\n\n在下面的示例中，where 子句筛选出除小于五的数字外的所有数字。 如果删除 where 子句，则会返回数据源中的所有数字。 表达式 num < 5 是应用于每个元素的谓词。\n\n```csharp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n一个 where 子句可以包含一个或多个返回布尔值的方法。 在下面的示例中，where 子句使用一种方法来确定范围变量的当前值是偶数还是奇数。\n\n```csharp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n"
}
