{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2e10809c",
   "metadata": {},
   "source": [
    "# Variables\n",
    "\n",
    "These names associated with a data storage location are called\n",
    "*variables*. In other words, variables represent the locations of\n",
    "objects in memory. Some general rules for C# variables are:\n",
    "\n",
    "- Every variable has a **type** that determines what values can be stored in the variable.\n",
    "- The C# compiler guarantees that values stored in variables are always of the appropriate type.\n",
    "- The value of a variable can be changed through **assignment** or through use of the ++ and -- operators.\n",
    "- Variables are either initially assigned or initially unassigned.\n",
    "\n",
    "Variables can have local scope or global scope:\n",
    "\n",
    "- Local variables are declared within a method and can only be accessed\n",
    "  within that method.\n",
    "- Global variables typically refer to static fields that are accessible\n",
    "  throughout the class.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8948e59",
   "metadata": {},
   "source": "## Declaring Local Variables\n\nA declaration statement declares a new local variable, local constant, or local\nreference variable. To declare a local variable, specify a type and provide\na variable name. You can declare multiple variables of the same type in one\nstatement:\n\n> `type variableName;`\n\nIn this syntax,\n\n- **type**\n  is a C# type (such as int or string),\n- **variableName**\n  is the name of the variable (such as x or name)\n- the semicolon `;`\n  is the statement terminator.\n\nFor example, you may declare the following variables\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f33b8d06",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "string greeting;     // declaring one string variable\n",
    "int a, b, c;         // declaring multiple int variables\n",
    "List<double> xs;     // a reference type (double list) variable\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e672be9",
   "metadata": {},
   "source": [
    "\n",
    "You can also provide initial values when declaring a variable.\n",
    "The syntax is:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "68e265be",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "type variableName = value;\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "efe6322d",
   "metadata": {},
   "source": [
    "\n",
    "For example,\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0ca6716d",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "string greeting = \"Hello\";\n",
    "int a = 3, b = 2, c = a + b;\n",
    "List<double> xs = new();\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0488e2d6",
   "metadata": {},
   "source": [
    "\n",
    "In this syntax,\n",
    "\n",
    "- the equal sign `=`\n",
    "  is the assignment operator (note that it is not the equal sign in mathematics)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c99834e4",
   "metadata": {},
   "source": "## The `var` Keyword\n\nLocal variables can be declared without giving an explicit type. The complier\nwill then infer the type of a variable from its initialization expression.\nThe keyword `var` is used in case of this. For example:\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "94ab3389",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "var greeting = \"Hello\";\n",
    "Console.WriteLine(greeting.GetType());  // output: System.String\n",
    "\n",
    "var a = 100;\n",
    "Console.WriteLine(a.GetType());  // output: System.Int32\n",
    "\n",
    "var xs = new List<double>();\n",
    "Console.WriteLine(xs.GetType());  // output: System.Collections.Generic.List`1[System.Double]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bff7851e",
   "metadata": {},
   "source": "## Assignment Statements\n\nIf you need to change\nthe value to a variable, you need to use the **assignment statement**.\nNote that an assignment statement is read from right to left. For example, if we\ncreate a variable \"area\" and assign the value of \"width * height\" to it like:\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58e4178f",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "area = width * height;\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "13ffa66c",
   "metadata": {},
   "source": [
    "\n",
    "The assignment statement starts by evaluating the **expression** on the right-hand side: `width * height`. Since width * height is an\n",
    "expression, the expression will be evaluated to a value like when evaluating an\n",
    "expression in math, so the values are substituted as\n",
    "\n",
    "```none\n",
    "5 * 7\n",
    "```\n",
    "\n",
    "which is then evaluates to 35 and finally assigned to the variable, `area`, on the left.\n",
    "The whole block of code could look something like follows. You may notice that we\n",
    "are operating with three variables here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1181fd0d",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "int width = 5, height, area;\n",
    "height = 7;\n",
    "area = width * height;\n",
    "area"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "57f7713d",
   "metadata": {},
   "source": [
    "In the example above,\n",
    "`width * height`, as an expression, evaluates to a value; while\n",
    "`int width = 5, height, area;` is a declaration statement and `height = 7;`\n",
    "an assignment statement.\n",
    "\n",
    "You should also notice that the value of the most *recent* assignment is\n",
    "remembered until reassigned. Also, it is common to use the same variable name\n",
    "when we intend to change the value to the variable without keeping the previous\n",
    "value, and after the initial declaration you don't need to declare type anymore:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e9bba53d",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "int a = 10;\n",
    "a = 100;       // reassignment\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5d92360f",
   "metadata": {},
   "source": [
    "\n",
    "To further illustrate how expression and statement work in C#, or in programming\n",
    "languages in general, we can take a look at the example as follows. In this case,\n",
    "we are making two assignment statements: one with a literal value and one with\n",
    "an expression:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6400ac7a",
   "metadata": {
    "language_info": {
     "name": "polyglot-notebook"
    },
    "polyglot_notebook": {
     "kernelName": "csharp"
    },
    "vscode": {
     "languageId": "polyglot-notebook"
    }
   },
   "outputs": [],
   "source": [
    "int n = 7;\n",
    "n = n + 1;\n",
    "n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc7c2227",
   "metadata": {},
   "source": [
    "In short piece of code above, we have an initial assignment statement (`n = 7`),\n",
    "a variable reassignment (`n = n + 1`) involving an expression `n + 1`, and\n",
    "finally the *new* value of `n` is 8, replacing the old 7. \\*\\* note that we are\n",
    "using a REPL and that is why we are able to type the variable name and hit Enter\n",
    "to see the value."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f4b2f40",
   "metadata": {},
   "source": [
    "## Variable, Identifiers, and Literals\n",
    "\n",
    "In programming languages, an **identifier** is defined as the name assigned to a\n",
    "entity (class, interface, struct, delegate, or enum), member, *variable*, function,\n",
    "method, or namespace, etc. A variable is an identifier/name assigned to a\n",
    "memory location that stores a value or object reference.\n",
    "\n",
    "**Literals**: Expressions with straight values such as `7` or `1.23` or `\"hello\"`\n",
    "are called *literals* because they *literally* represent what they are.\n",
    "For example:\n",
    "\n",
    "- A `bool` variable has two literal values: true or false.\n",
    "- A string literal is a series of characters delimited by double quotes in one line.\n",
    "- An integral numeric type can have three kinds of literals: decimal, hexadecimal, and binary."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "88baed1c",
   "metadata": {},
   "source": "## Naming Convention of Identifiers\n\nSome of the common conventions [^footnote-1] to follow when naming C# identifiers are:\n\n- The characters must all be letters, digits, or underscores `_`,\n  and must start with a letter.\n\n% - *Reserved keywords* may not be used to name your own identifiers unless\n% a ``@`` is prefixed. Common IDE's will be able to catch this.\n\n- C# is case sensitive: The identifiers `name`, `NAME`, and `NaMe`\n  are different.\n- By convention, C# programs use **PascalCase** for namespace,\n  class, and method names and **camelCase** for **variable** and\n  method parameters. [^footnote-2]\n- Use meaningful and descriptive names for variables, methods, and classes.\n- Avoid keywords when naming identifiers."
  },
  {
   "cell_type": "markdown",
   "id": "7db045e4",
   "metadata": {},
   "source": [
    "```{index} keyword\n",
    "```\n",
    "## Keywords\n",
    "\n",
    "Keywords are predefined, reserved *identifiers* that have special meanings to the\n",
    "compiler and can not be used as identifiers (including variable names) in your program\n",
    "unless they include @ as a prefix. Current **reserved keywords** are as the table blow.\n",
    "You can see that many of the data type names are reserved keywords.\n",
    "\n",
    "```{eval-rst}\n",
    "==========  ==========  ==========  ==========  ==========\n",
    "abstract    do          in          protected   true\n",
    "as          double      int         public      try\n",
    "base        else        interface   readonly    typeof\n",
    "bool        enum        internal    ref         uint\n",
    "break       event       is          return      ulong\n",
    "byte        explicit    lock        sbyte       unchecked\n",
    "case        extern      long        sealed      unsafe\n",
    "catch       false       namespace   short       ushort\n",
    "char        finally     new         sizeof      using\n",
    "checked     fixed       null        stackalloc  virtual\n",
    "class       float       object      static      void\n",
    "const       for         operator    string      volatile\n",
    "continue    foreach     out         struct      while\n",
    "decimal     goto        override    switch\n",
    "default     if          params      this\n",
    "delegate    implicit    private     throw\n",
    "==========  ==========  ==========  ==========  ==========\n",
    "```\n",
    "\n",
    "C# has another set of keywords called contextual keywords that are keywords with special meaning\n",
    "in specific context and may be used as identifiers outside the program context.\n",
    "\n",
    "```{rubric} Footnotes\n",
    "```\n",
    "\n",
    "[^footnote-1]: For C# identifier naming conventions, see: <https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/identifier-names>.\n",
    "    Also, for coding conventions, see <https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions#style-guidelines>.\n",
    "\n",
    "[^footnote-2]: There are also snake_case, commonly used in Python, and kebab-case, commonly used in CSS."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2026ac8d",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": ".NET (C#)",
   "language": "C#",
   "name": ".net-csharp"
  },
  "language_info": {
   "name": "csharp"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}