{
 "nbformat": 4,
 "nbformat_minor": 5,
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "name": "C#"
  }
 },
 "cells": [
  {
   "cell_type": "markdown",
   "id": "p01",
   "metadata": {},
   "source": [
    "# Pattern Matching\n\n",
    "Pattern matching lets you test a value's *shape* or *type* and branch accordingly.\n",
    "C# has evolved this from simple `is` checks to expressive `switch` expressions.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "p02",
   "metadata": {},
   "source": [
    "## The `is` Operator\n\n",
    "`is` tests type and, if it matches, assigns the value to a new variable in one step.\n"
   ]
  },
  {
   "cell_type": "code",
   "id": "p03",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "object val = 42;\n\n",
    "if (val is int n)\n",
    "    Console.WriteLine($\"It's an int: {n * 2}\");  // It's an int: 84\n\n",
    "object name = \"Alice\";\n",
    "if (name is string s && s.Length > 3)\n",
    "    Console.WriteLine($\"Long name: {s}\");  // Long name: Alice\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "p04",
   "metadata": {},
   "source": [
    "## Switch Expression\n\n",
    "The modern `switch` expression is concise — each arm is `pattern => result`.\n"
   ]
  },
  {
   "cell_type": "code",
   "id": "p05",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "static string Classify(int n) => n switch\n",
    "{\n",
    "    < 0  => \"negative\",\n",
    "    0    => \"zero\",\n",
    "    < 10 => \"small positive\",\n",
    "    _    => \"large positive\"   // _ is the discard (default)\n",
    "};\n\n",
    "Console.WriteLine(Classify(-5));  // negative\n",
    "Console.WriteLine(Classify(0));   // zero\n",
    "Console.WriteLine(Classify(7));   // small positive\n",
    "Console.WriteLine(Classify(42));  // large positive\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "p06",
   "metadata": {},
   "source": [
    "## Type Patterns\n\n",
    "Switch on the runtime type of an object — useful in OOP hierarchies.\n"
   ]
  },
  {
   "cell_type": "code",
   "id": "p07",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "static string Describe(object obj) => obj switch\n",
    "{\n",
    "    int i    => $\"int: {i}\",\n",
    "    double d => $\"double: {d:F2}\",\n",
    "    string s => $\"string of length {s.Length}\",\n",
    "    null     => \"null\",\n",
    "    _        => \"something else\"\n",
    "};\n\n",
    "Console.WriteLine(Describe(42));       // int: 42\n",
    "Console.WriteLine(Describe(3.14));     // double: 3.14\n",
    "Console.WriteLine(Describe(\"hello\")); // string of length 5\n",
    "Console.WriteLine(Describe(null));     // null\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "p08",
   "metadata": {},
   "source": [
    "## When Guards\n\n",
    "Add a `when` clause to a pattern arm for extra conditions.\n"
   ]
  },
  {
   "cell_type": "code",
   "id": "p09",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "static string Grade(int score) => score switch\n",
    "{\n",
    "    >= 90 => \"A\",\n",
    "    >= 80 => \"B\",\n",
    "    >= 70 => \"C\",\n",
    "    >= 60 => \"D\",\n",
    "    _     => \"F\"\n",
    "};\n\n",
    "Console.WriteLine(Grade(95));  // A\n",
    "Console.WriteLine(Grade(83));  // B\n",
    "Console.WriteLine(Grade(55));  // F\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "p10",
   "metadata": {},
   "source": [
    "## Tuple Patterns\n\n",
    "Match against multiple values at once by switching on a tuple.\n"
   ]
  },
  {
   "cell_type": "code",
   "id": "p11",
   "metadata": {},
   "execution_count": null,
   "outputs": [],
   "source": [
    "static string RPS(string a, string b) => (a, b) switch\n",
    "{\n",
    "    (\"Rock\",     \"Scissors\") => \"Player 1 wins\",\n",
    "    (\"Scissors\", \"Paper\")    => \"Player 1 wins\",\n",
    "    (\"Paper\",    \"Rock\")     => \"Player 1 wins\",\n",
    "    var (x, y) when x == y   => \"Draw\",\n",
    "    _                        => \"Player 2 wins\"\n",
    "};\n\n",
    "Console.WriteLine(RPS(\"Rock\", \"Scissors\"));  // Player 1 wins\n",
    "Console.WriteLine(RPS(\"Rock\", \"Rock\"));      // Draw\n",
    "Console.WriteLine(RPS(\"Rock\", \"Paper\"));     // Player 2 wins\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "p12",
   "metadata": {},
   "source": [
    "## Practice\n\n",
    "1. Write `string Season(int month)` using a switch expression that returns `\"Spring\"`, `\"Summer\"`, `\"Fall\"`, or `\"Winter\"`.\n",
    "2. Write `string HttpStatus(int code)` that returns a description for `200`, `404`, `500`, and a default `\"Unknown\"`.\n",
    "3. Write a switch expression that classifies a `char` as `'vowel'`, `'digit'`, or `'other'`.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "footnotes",
   "metadata": {},
   "source": "```{rubric} Footnotes\n```\n"
  }
 ]
}