cs11dotnet7/notebooks/Chapter02.dib
2023-07-19 08:18:31 +01:00

437 lines
10 KiB
Plaintext

#!csharp
#!markdown
# Chapter 2 - Speaking C#
#!csharp
using static System.Console;
#!markdown
## Showing the compiler version
#!csharp
// #error version
#!markdown
## Help for writing correct code
In a .NET Interactive notebook, you do not need to end the last statement with a semi-colon.
#!csharp
// with two compile errors
Console.Writeline("Hello World!")
// fixed
Console.WriteLine("Hello World!")
#!markdown
## Revealing the extent of the C# vocabulary
When running this code inside a .NET Interactive notebook, it lists all possible assemblies, including some used by the extension like `Microsoft.DotNet.Interactive`.
#!csharp
using System.Linq;
using System.Reflection;
// loop through the assemblies that this app references
foreach (var r in Assembly.GetEntryAssembly()
.GetReferencedAssemblies())
{
// load the assembly so we can read its details
var a = Assembly.Load(new AssemblyName(r.FullName));
// declare a variable to count the number of methods
int methodCount = 0;
// loop through all the types in the assembly
foreach (var t in a.DefinedTypes)
{
// add up the counts of methods
methodCount += t.GetMethods().Count();
}
// output the count of types and their methods
Console.WriteLine(
"{0:N0} types with {1:N0} methods in {2} assembly.",
arg0: a.DefinedTypes.Count(),
arg1: methodCount,
arg2: r.Name);
}
#!markdown
## Naming things and assigning values
#!csharp
// let the heightInMetres variable become equal to the value 1.88
double heightInMetres = 1.88;
Console.WriteLine($"The variable {nameof(heightInMetres)} has the value {heightInMetres}.");
#!markdown
## Storing text
#!csharp
char letter = 'A'; // assigning literal characters
char digit = '1';
char symbol = '$';
char userChoice = GetSomeKeystroke(); // assigning from a fictitious function
string firstName = "Bob"; // assigning literal strings
string lastName = "Smith";
string phoneNumber = "(215) 555-4256";
// assigning a string returned from a fictitious function
string address = GetAddressFromDatabase(id: 563);
#!markdown
## Understanding verbatim strings
In a .NET Interactive notebook, a brighter red color is used for escaped characters inside a string value to make them easier to see.
`\t` means tab. `\b` means backspace. `\s` does is not a valid escape character.
#!csharp
string fullNameWithTabSeparator = "Bob\tSmith";
string filePath = "C:\televisions\sony\bravia.txt";
#!csharp
string filePath = @"C:\televisions\sony\bravia.txt";
#!markdown
## Storing numbers
#!csharp
// unsigned integer means positive whole number or 0
uint naturalNumber = 23;
// integer means negative or positive whole number or 0
int integerNumber = -23;
// float means single-precision floating point
// F suffix makes it a float literal
float realNumber = 2.3F;
// double means double-precision floating point
double anotherRealNumber = 2.3; // double literal
#!markdown
## Storing whole numbers
#!csharp
// three variables that store the number 2 million
int decimalNotation = 2_000_000;
int binaryNotation = 0b_0001_1110_1000_0100_1000_0000;
int hexadecimalNotation = 0x_001E_8480;
// check the three variables have the same value
// both statements output true
Console.WriteLine($"{decimalNotation == binaryNotation}");
Console.WriteLine(
$"{decimalNotation == hexadecimalNotation}");
#!markdown
## Writing code to explore number sizes
#!csharp
Console.WriteLine($"int uses {sizeof(int)} bytes and can store numbers in the range {int.MinValue:N0} to {int.MaxValue:N0}.");
Console.WriteLine($"double uses {sizeof(double)} bytes and can store numbers in the range {double.MinValue:N0} to {double.MaxValue:N0}.");
Console.WriteLine($"decimal uses {sizeof(decimal)} bytes and can store numbers in the range {decimal.MinValue:N0} to {decimal.MaxValue:N0}.");
#!markdown
## Comparing double and decimal
#!csharp
Console.WriteLine("Using doubles:");
double a = 0.1;
double b = 0.2;
if (a + b == 0.3)
{
Console.WriteLine($"{a} + {b} equals 0.3");
}
else
{
Console.WriteLine($"{a} + {b} does NOT equal 0.3");
}
#!csharp
Console.WriteLine("Using decimals:");
decimal c = 0.1M; // M suffix means a decimal literal value
decimal d = 0.2M;
if (c + d == 0.3M)
{
Console.WriteLine($"{c} + {d} equals 0.3");
}
else
{
Console.WriteLine($"{c} + {d} does NOT equal 0.3");
}
#!markdown
## Storing Booleans
#!csharp
bool happy = true;
bool sad = false;
#!markdown
## Storing any type of object
#!csharp
object height = 1.88; // storing a double in an object
object name = "Amir"; // storing a string in an object
Console.WriteLine($"{name} is {height} metres tall.");
//int length1 = name.Length; // gives compile error!
int length2 = ((string)name).Length; // tell compiler it is a string
Console.WriteLine($"{name} has {length2} characters.");
#!markdown
## Storing dynamic types
#!csharp
// storing a string in a dynamic object
// string has a Length property
dynamic anotherName = "Ahmed";
// int does not have a Length property
anotherName = 12;
// an array of any type has a Length property
anotherName = new[] { 3, 5, 7 };
// this compiles but would throw an exception at run-time
// if you later store a data type that does not have a
// property named Length
Console.WriteLine($"Length is {anotherName.Length}");
#!markdown
## Specifying and inferring the type of a local variable
*Note*: click **Execute Code** in the following cell to import the namespaces for the subsequent code cell.
#!csharp
using System.IO;
using System.Xml;
#!csharp
var population = 66_000_000; // 66 million in UK
var weight = 1.88; // in kilograms
var price = 4.99M; // in pounds sterling
var fruit = "Apples"; // strings use double-quotes
var letter = 'Z'; // chars use single-quotes
var happy = true; // Booleans have value of true or false
// good use of var because it avoids the repeated type
// as shown in the more verbose second statement
var xml1 = new XmlDocument();
XmlDocument xml2 = new XmlDocument();
// bad use of var because we cannot tell the type, so we
// should use a specific type declaration as shown in
// the second statement
var file1 = File.CreateText(@"C:\something.txt");
StreamWriter file2 = File.CreateText(@"C:\something.txt");
XmlDocument xml3 = new(); // target-typed new in C# 9 or later
#!csharp
class Person
{
public DateTime BirthDate;
}
Person kim = new();
kim.BirthDate = new(1967, 12, 26); // instead of: new DateTime(1967, 12, 26)
#!markdown
## Getting default values for types
The default value of a `string` is `null` which outputs as nothing.
#!csharp
Console.WriteLine($"default(int) = {default(int)}");
Console.WriteLine($"default(bool) = {default(bool)}");
Console.WriteLine(
$"default(DateTime) = {default(DateTime)}");
Console.WriteLine(
$"default(string) = {default(string)}");
#!csharp
int number = 13;
Console.WriteLine($"number has been set to: {number}");
number = default;
Console.WriteLine($"number has been reset to its default: {number}");
#!markdown
## Storing multiple values an array
#!csharp
string[] names; // can reference any array of strings
// allocating memory for four strings in an array
names = new string[4];
// storing items at index positions
names[0] = "Kate";
names[1] = "Jack";
names[2] = "Rebecca";
names[3] = "Tom";
// looping through the names
for (int i = 0; i < names.Length; i++)
{
// output the item at index position i
Console.WriteLine(names[i]);
}
#!markdown
## Formatting using numbered positional arguments
#!csharp
using static System.Console;
#!csharp
int numberOfApples = 12;
decimal pricePerApple = 0.35M;
WriteLine(
format: "{0} apples costs {1:C}",
arg0: numberOfApples,
arg1: pricePerApple * numberOfApples);
string formatted = string.Format(
format: "{0} apples costs {1:C}",
arg0: numberOfApples,
arg1: pricePerApple * numberOfApples);
//WriteToFile(formatted); // writes the string into a file
#!markdown
## Formatting using interpolated strings
#!csharp
WriteLine($"{numberOfApples} apples costs {pricePerApple * numberOfApples:C}");
#!markdown
## Understanding format strings
#!csharp
string applesText = "Apples";
int applesCount = 1234;
string bananasText = "Bananas";
int bananasCount = 56789;
WriteLine(
format: "{0,-8} {1,6:N0}",
arg0: "Name",
arg1: "Count");
WriteLine(
format: "{0,-8} {1,6:N0}",
arg0: applesText,
arg1: applesCount);
WriteLine(
format: "{0,-8} {1,6:N0}",
arg0: bananasText,
arg1: bananasCount);
#!markdown
## Getting text input from the user
.NET Interactive notebooks do not support `ReadLine()` so in the following code we must set literal string values for the two variables.
#!csharp
Write("Type your first name and press ENTER: ");
string firstName = "Gary"; // cannot use Console.ReadLine()
Write("Type your age and press ENTER: ");
string age = "34"; // cannot use Console.ReadLine()
WriteLine(
$"Hello {firstName}, you look good for {age}.");
#!markdown
## Getting key input from the user
`Console.ReadKey()` does not work in a .NET notebook.
#!markdown
## Getting arguments
Arguments cannot be passed to a .NET notebook.
#!markdown
## Exercise 3 - Practice number sizes and ranges
#!csharp
WriteLine("--------------------------------------------------------------------------");
WriteLine("Type Byte(s) of memory Min Max");
WriteLine("--------------------------------------------------------------------------");
WriteLine($"sbyte {sizeof(sbyte),-4} {sbyte.MinValue,30} {sbyte.MaxValue,30}");
WriteLine($"byte {sizeof(byte),-4} {byte.MinValue,30} {byte.MaxValue,30}");
WriteLine($"short {sizeof(short),-4} {short.MinValue,30} {short.MaxValue,30}");
WriteLine($"ushort {sizeof(ushort),-4} {ushort.MinValue,30} {ushort.MaxValue,30}");
WriteLine($"int {sizeof(int),-4} {int.MinValue,30} {int.MaxValue,30}");
WriteLine($"uint {sizeof(uint),-4} {uint.MinValue,30} {uint.MaxValue,30}");
WriteLine($"long {sizeof(long),-4} {long.MinValue,30} {long.MaxValue,30}");
WriteLine($"ulong {sizeof(ulong),-4} {ulong.MinValue,30} {ulong.MaxValue,30}");
WriteLine($"float {sizeof(float),-4} {float.MinValue,30} {float.MaxValue,30}");
WriteLine($"double {sizeof(double),-4} {double.MinValue,30} {double.MaxValue,30}");
WriteLine($"decimal {sizeof(decimal),-4} {decimal.MinValue,30} {decimal.MaxValue,30}");
WriteLine("--------------------------------------------------------------------------");