{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Everything in C# is an object\n", "\n", "As C# is an object oriented language, everything we want to work with is an object. Objects can be declared of various **TYPES** and then interacted with.\n", "\n", "Let's consider our deck of cards example. We can model all different states and information about the deck of cards using variables, and we'll use that as a sample scenario throughout this module.\n", "\n", "The simplest types in C# are called [**Built-In Types**](https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/built-in-types?WT.mc_id=visualstudio-twitch-jefritz) and have short keywords available that we can use to declare the type of a variable:\n", "\n", "| Keyword | Type Name | Description | Valid Values |\n", "| ---- | ---- | ---- | ---- |\n", "| bool | System.Boolean | Boolean value that can be true or false | true, false |\n", "| byte | System.Byte | Unsigned 8-bit integer | 0 to 255 |\n", "| sbyte | System.SByte | Signed 8-bit integer | -127 to 127 |\n", "| char | System.Char | Single character storage in UTF-16 format | Valid UTF-16 characters |\n", "| decimal | System.Decimal | Floating point number with 28-29 digits of precision in 16 bytes | ±1.0 x 10-28 to ±7.9228 x 1028 |\n", "| double | System.Double | Floating point number with 15-17 digits of precision in 8 bytes | ±5.0 × 10−324 to ±1.7 × 10308 |\n", "| float | System.Single | Floating point number with 6-9 digits of precision in 4 bytes | ±1.5 x 10−45 to ±3.4 x 1038 |\n", "| int | System.Int32 | Signed 32-bit integer | -2,147,483,648 to 2,147,483,647 |\n", "| uint | System.UInt32 | Unsigned 32-bit integer | 0 to 4,294,967,295 |\n", "| nint | System.IntPtr | Platform dependent integer | Signed 32-bit or 64-bit integer |\n", "| nuint | System.UIntPtr | Platform dependent unsigned integer | Unsigned 32-bit or 64-bit integer |\n", "| long | System.Int64 | Signed 64-bit integer | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |\n", "| ulong | System.UInt64 | Unsigned 64-bit integer | 0 to 18,446,744,073,709,551,615 |\n", "| short | System.Int16 | Signed 16-bit integer | -32,768 to 32,767 |\n", "| ushort | System.UInt16 | Unsigned 16-bit integer | 0 to 65,535 |\n", "\n", "We can define variables, in-memory storage for a type, by preceding the name of the variable we would like to create with the type of the variable we are creating." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "int countOfCards;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That's not very exciting, however we created a 32-bit integer named `countOfCards` that we could use elsewhere in our code.  We can initialize a variable with an `=` assignment at the time of declaration." ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "int countOfCards = 52; // 52 cards in the deck\n", "char suit = 'H'; // The suit of a card is identified by a single character, H for hearts\n", "bool faceDown = true; // A card is face down" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Large numbers can get difficult for us to read when we assign them like this. Fortunately, C# allows us to use an underscore character `_` to separate digits in ANY grouping that you'd like and the compiler will simply ignore the character." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "int oneMillionCards = 1_000_000;\n", "int anotherMillion = 1000_000;\n", "int aMillionAgain = 100000_0;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Perhaps you would like to assign numbers using hexadecimal or binary values. Those are supported with the `0x` prefix for hexadecimal and `0b` or `0B` prefix for binary." ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "data": { "text/html": [ "
2024
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "int thisYear = 2024;\n", "int thisYearInHex = 0x7E8;\n", "int thisYearInBinary = 0b_0111_1110_1000;\n", "\n", "thisYearInBinary" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These variables can be changed elsewhere in our application. If we wanted to change our cards to be face up, we could re-assign the `faceDown` variable like this:" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "faceDown = false;" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that we are not declaring the type, that only needs to be done once, and we are just changing the value assigned to the variable.\n", "\n", "### The var keyword\n", "Sometimes, its a little cumbersome to declare a variable, assign a value, and have to specify the type before it.  C# has built-in type inference and you can use the `var` keyword to force the compiler to detect the actual type being created  and set the variable to the type of the value being assigned." ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [ { "data": { "text/html": [ "System.Boolean" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "var countOfCards = 52.0;\n", "var suit = 'H';\n", "var faceDown = true;\n", "\n", "display(faceDown.GetType());" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can **ONLY** use the `var` keyword when creating and assigning the variable in one statement.\n", "\n", "### Real Literals\n", "When you declare a numeric type, by default it is allocated as an int or a 32-bit integer type. We can instead declare double, float, and decimal types with simple numeric notation, but we need to force the literal numbers we assign to be the correct type to match the variable type expected.\n", "\n", "To do this, we add a `d`, `f`, or `m` suffix to a number being assigned.\n" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "dotnet_interactive": { "language": "csharp" }, "polyglot_notebook": { "kernelName": "csharp" } }, "outputs": [], "source": [ "var angleCardIsTurned = 45.0m;" ] } ], "metadata": { "kernelspec": { "display_name": ".NET (C#)", "language": "C#", "name": ".net-csharp" }, "language_info": { "name": "polyglot-notebook" }, "polyglot_notebook": { "kernelInfo": { "defaultKernelName": "csharp", "items": [ { "aliases": [], "languageName": "csharp", "name": "csharp" } ] } } }, "nbformat": 4, "nbformat_minor": 2 }