From bf63cf7d4b58faa9cbf3d3a94448fb6a23d3fcd2 Mon Sep 17 00:00:00 2001 From: Mark J Price Date: Sat, 17 Sep 2022 14:09:41 +0100 Subject: [PATCH] Initial commit --- vs4win/Chapter03/Arrays/Program.cs | 36 ++++++ .../Chapter03/SelectionStatements/Animals.cs | 16 +++ .../Chapter03/SelectionStatements/Program.cs | 109 +++++++++--------- vscode/Chapter03/Arrays/Program.cs | 36 ++++++ .../Chapter03/SelectionStatements/Animals.cs | 16 +++ .../Chapter03/SelectionStatements/Program.cs | 109 +++++++++--------- 6 files changed, 212 insertions(+), 110 deletions(-) create mode 100644 vs4win/Chapter03/SelectionStatements/Animals.cs create mode 100644 vscode/Chapter03/SelectionStatements/Animals.cs diff --git a/vs4win/Chapter03/Arrays/Program.cs b/vs4win/Chapter03/Arrays/Program.cs index a978d04..0dbc192 100644 --- a/vs4win/Chapter03/Arrays/Program.cs +++ b/vs4win/Chapter03/Arrays/Program.cs @@ -68,3 +68,39 @@ for (int row = 0; row <= jagged.GetUpperBound(0); row++) WriteLine($"Row {row}, Column {col}: {jagged[row][col]}"); } } + +// Pattern matching with arrays + +int[] sequentialNumbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; +int[] oneTwoNumbers = new int[] { 1, 2 }; +int[] oneTwoTenNumbers = new int[] { 1, 2, 10 }; +int[] oneTwoThreeTenNumbers = new int[] { 1, 2, 3, 10 }; +int[] primeNumbers = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; +int[] fibonacciNumbers = new int[] { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; +int[] emptyNumbers = new int[] { }; +int[] threeNumbers = new int[] { 9, 7, 5 }; +int[] sixNumbers = new int[] { 9, 7, 5, 4, 2, 10 }; + +WriteLine($"{nameof(sequentialNumbers)}: {CheckSwitch(sequentialNumbers)}"); +WriteLine($"{nameof(oneTwoNumbers)}: {CheckSwitch(oneTwoNumbers)}"); +WriteLine($"{nameof(oneTwoTenNumbers)}: {CheckSwitch(oneTwoTenNumbers)}"); +WriteLine($"{nameof(oneTwoThreeTenNumbers)}: {CheckSwitch(oneTwoThreeTenNumbers)}"); +WriteLine($"{nameof(primeNumbers)}: {CheckSwitch(primeNumbers)}"); +WriteLine($"{nameof(fibonacciNumbers)}: {CheckSwitch(fibonacciNumbers)}"); +WriteLine($"{nameof(emptyNumbers)}: {CheckSwitch(emptyNumbers)}"); +WriteLine($"{nameof(threeNumbers)}: {CheckSwitch(threeNumbers)}"); +WriteLine($"{nameof(sixNumbers)}: {CheckSwitch(sixNumbers)}"); + +static string CheckSwitch(int[] values) => values switch +{ + [] => "Empty array", + [1, 2, _, 10] => "Contains 1, 2, any single number, 10.", + [1, 2, .., 10] => "Contains 1, 2, any range including empty, 10.", + [1, 2] => "Contains 1 then 2.", + [int item1, int item2, int item3] => + $"Contains {item1} then {item2} then {item3}.", + [0, _] => "Starts with 0, then one other number.", + [0, ..] => "Starts with 0, then any range of numbers.", + [2, .. int[] others] => $"Starts with 2, then {others.Length} more numbers.", + [..] => "Any items in any order.", +}; diff --git a/vs4win/Chapter03/SelectionStatements/Animals.cs b/vs4win/Chapter03/SelectionStatements/Animals.cs new file mode 100644 index 0000000..5c0ea8a --- /dev/null +++ b/vs4win/Chapter03/SelectionStatements/Animals.cs @@ -0,0 +1,16 @@ +class Animal // This is the base type for all animals. +{ + public string? Name; + public DateTime Born; + public byte Legs; +} + +class Cat : Animal // This is a subtype of animal. +{ + public bool IsDomestic; +} + +class Spider : Animal // This is another subtype of animal. +{ + public bool IsPoisonous; +} diff --git a/vs4win/Chapter03/SelectionStatements/Program.cs b/vs4win/Chapter03/SelectionStatements/Program.cs index ab25862..0905e5c 100644 --- a/vs4win/Chapter03/SelectionStatements/Program.cs +++ b/vs4win/Chapter03/SelectionStatements/Program.cs @@ -46,61 +46,60 @@ WriteLine("After end of switch"); A_label: WriteLine($"After A_label"); -// string path = "/Users/markjprice/cs11dotnet7/Chapter03"; -string path = @"C:\cs11dotnet7\Chapter03"; -Stream? s; +// Pattern matching with the switch statement -Write("Press R for read-only or W for writeable: "); -ConsoleKeyInfo key = ReadKey(); - -if (key.Key == ConsoleKey.R) +Animal?[] animals = new Animal?[] { - s = File.Open( - Path.Combine(path, "file.txt"), - FileMode.OpenOrCreate, - FileAccess.Read); -} -else -{ - s = File.Open( - Path.Combine(path, "file.txt"), - FileMode.OpenOrCreate, - FileAccess.Write); -} -WriteLine(); - -string message; -switch (s) -{ - case FileStream writeableFile when s.CanWrite: - message = "The stream is a file that I can write to."; - break; - case FileStream readOnlyFile: - message = "The stream is a read-only file."; - break; - case MemoryStream ms: - message = "The stream is a memory address."; - break; - default: // always evaluated last despite its current position - message = "The stream is some other type."; - break; - case null: - message = "The stream is null."; - break; -} -WriteLine(message); - -message = s switch -{ - FileStream writeableFile when s.CanWrite - => "The stream is a file that I can write to.", - FileStream readOnlyFile - => "The stream is a read-only file.", - MemoryStream ms - => "The stream is a memory address.", - null - => "The stream is null.", - _ - => "The stream is some other type." + new Cat { Name = "Karen", Born = new(year: 2022, month: 8, day: 23), + Legs = 4, IsDomestic = true }, + null, + new Cat { Name = "Mufasa", Born = new(year: 1994, month: 6, day: 12) }, + new Spider { Name = "Sid Vicious", Born = DateTime.Today, + IsPoisonous = true}, + new Spider { Name = "Captain Furry", Born = DateTime.Today } }; -WriteLine(message); + +foreach (Animal? animal in animals) +{ + string message; + + switch (animal) + { + case Cat fourLeggedCat when fourLeggedCat.Legs == 4: + message = $"The cat named {fourLeggedCat.Name} has four legs."; + break; + case Cat wildCat when wildCat.IsDomestic == false: + message = $"The non-domestic cat is named {wildCat.Name}."; + break; + case Cat cat: + message = $"The cat is named {cat.Name}."; + break; + default: // default is always evaluated last + message = $"The animal named {animal.Name} is a {animal.GetType().Name}."; + break; + case Spider spider when spider.IsPoisonous: + message = $"The {spider.Name} spider is poisonous. Run!"; + break; + case null: + message = "The animal is null."; + break; + } + WriteLine($"switch statement: {message}"); + + message = animal switch + { + Cat fourLeggedCat when fourLeggedCat.Legs == 4 + => $"The cat named {fourLeggedCat.Name} has four legs.", + Cat wildCat when wildCat.IsDomestic == false + => $"The non-domestic cat is named {wildCat.Name}.", + Cat cat + => $"The cat is named {cat.Name}.", + Spider spider when spider.IsPoisonous + => $"The {spider.Name} spider is poisonous. Run!", + null + => "The animal is null.", + _ + => $"The animal named {animal.Name} is a {animal.GetType().Name}." + }; + WriteLine($"switch expression: {message}"); +} diff --git a/vscode/Chapter03/Arrays/Program.cs b/vscode/Chapter03/Arrays/Program.cs index a978d04..0dbc192 100644 --- a/vscode/Chapter03/Arrays/Program.cs +++ b/vscode/Chapter03/Arrays/Program.cs @@ -68,3 +68,39 @@ for (int row = 0; row <= jagged.GetUpperBound(0); row++) WriteLine($"Row {row}, Column {col}: {jagged[row][col]}"); } } + +// Pattern matching with arrays + +int[] sequentialNumbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; +int[] oneTwoNumbers = new int[] { 1, 2 }; +int[] oneTwoTenNumbers = new int[] { 1, 2, 10 }; +int[] oneTwoThreeTenNumbers = new int[] { 1, 2, 3, 10 }; +int[] primeNumbers = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; +int[] fibonacciNumbers = new int[] { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; +int[] emptyNumbers = new int[] { }; +int[] threeNumbers = new int[] { 9, 7, 5 }; +int[] sixNumbers = new int[] { 9, 7, 5, 4, 2, 10 }; + +WriteLine($"{nameof(sequentialNumbers)}: {CheckSwitch(sequentialNumbers)}"); +WriteLine($"{nameof(oneTwoNumbers)}: {CheckSwitch(oneTwoNumbers)}"); +WriteLine($"{nameof(oneTwoTenNumbers)}: {CheckSwitch(oneTwoTenNumbers)}"); +WriteLine($"{nameof(oneTwoThreeTenNumbers)}: {CheckSwitch(oneTwoThreeTenNumbers)}"); +WriteLine($"{nameof(primeNumbers)}: {CheckSwitch(primeNumbers)}"); +WriteLine($"{nameof(fibonacciNumbers)}: {CheckSwitch(fibonacciNumbers)}"); +WriteLine($"{nameof(emptyNumbers)}: {CheckSwitch(emptyNumbers)}"); +WriteLine($"{nameof(threeNumbers)}: {CheckSwitch(threeNumbers)}"); +WriteLine($"{nameof(sixNumbers)}: {CheckSwitch(sixNumbers)}"); + +static string CheckSwitch(int[] values) => values switch +{ + [] => "Empty array", + [1, 2, _, 10] => "Contains 1, 2, any single number, 10.", + [1, 2, .., 10] => "Contains 1, 2, any range including empty, 10.", + [1, 2] => "Contains 1 then 2.", + [int item1, int item2, int item3] => + $"Contains {item1} then {item2} then {item3}.", + [0, _] => "Starts with 0, then one other number.", + [0, ..] => "Starts with 0, then any range of numbers.", + [2, .. int[] others] => $"Starts with 2, then {others.Length} more numbers.", + [..] => "Any items in any order.", +}; diff --git a/vscode/Chapter03/SelectionStatements/Animals.cs b/vscode/Chapter03/SelectionStatements/Animals.cs new file mode 100644 index 0000000..5c0ea8a --- /dev/null +++ b/vscode/Chapter03/SelectionStatements/Animals.cs @@ -0,0 +1,16 @@ +class Animal // This is the base type for all animals. +{ + public string? Name; + public DateTime Born; + public byte Legs; +} + +class Cat : Animal // This is a subtype of animal. +{ + public bool IsDomestic; +} + +class Spider : Animal // This is another subtype of animal. +{ + public bool IsPoisonous; +} diff --git a/vscode/Chapter03/SelectionStatements/Program.cs b/vscode/Chapter03/SelectionStatements/Program.cs index ab25862..0905e5c 100644 --- a/vscode/Chapter03/SelectionStatements/Program.cs +++ b/vscode/Chapter03/SelectionStatements/Program.cs @@ -46,61 +46,60 @@ WriteLine("After end of switch"); A_label: WriteLine($"After A_label"); -// string path = "/Users/markjprice/cs11dotnet7/Chapter03"; -string path = @"C:\cs11dotnet7\Chapter03"; -Stream? s; +// Pattern matching with the switch statement -Write("Press R for read-only or W for writeable: "); -ConsoleKeyInfo key = ReadKey(); - -if (key.Key == ConsoleKey.R) +Animal?[] animals = new Animal?[] { - s = File.Open( - Path.Combine(path, "file.txt"), - FileMode.OpenOrCreate, - FileAccess.Read); -} -else -{ - s = File.Open( - Path.Combine(path, "file.txt"), - FileMode.OpenOrCreate, - FileAccess.Write); -} -WriteLine(); - -string message; -switch (s) -{ - case FileStream writeableFile when s.CanWrite: - message = "The stream is a file that I can write to."; - break; - case FileStream readOnlyFile: - message = "The stream is a read-only file."; - break; - case MemoryStream ms: - message = "The stream is a memory address."; - break; - default: // always evaluated last despite its current position - message = "The stream is some other type."; - break; - case null: - message = "The stream is null."; - break; -} -WriteLine(message); - -message = s switch -{ - FileStream writeableFile when s.CanWrite - => "The stream is a file that I can write to.", - FileStream readOnlyFile - => "The stream is a read-only file.", - MemoryStream ms - => "The stream is a memory address.", - null - => "The stream is null.", - _ - => "The stream is some other type." + new Cat { Name = "Karen", Born = new(year: 2022, month: 8, day: 23), + Legs = 4, IsDomestic = true }, + null, + new Cat { Name = "Mufasa", Born = new(year: 1994, month: 6, day: 12) }, + new Spider { Name = "Sid Vicious", Born = DateTime.Today, + IsPoisonous = true}, + new Spider { Name = "Captain Furry", Born = DateTime.Today } }; -WriteLine(message); + +foreach (Animal? animal in animals) +{ + string message; + + switch (animal) + { + case Cat fourLeggedCat when fourLeggedCat.Legs == 4: + message = $"The cat named {fourLeggedCat.Name} has four legs."; + break; + case Cat wildCat when wildCat.IsDomestic == false: + message = $"The non-domestic cat is named {wildCat.Name}."; + break; + case Cat cat: + message = $"The cat is named {cat.Name}."; + break; + default: // default is always evaluated last + message = $"The animal named {animal.Name} is a {animal.GetType().Name}."; + break; + case Spider spider when spider.IsPoisonous: + message = $"The {spider.Name} spider is poisonous. Run!"; + break; + case null: + message = "The animal is null."; + break; + } + WriteLine($"switch statement: {message}"); + + message = animal switch + { + Cat fourLeggedCat when fourLeggedCat.Legs == 4 + => $"The cat named {fourLeggedCat.Name} has four legs.", + Cat wildCat when wildCat.IsDomestic == false + => $"The non-domestic cat is named {wildCat.Name}.", + Cat cat + => $"The cat is named {cat.Name}.", + Spider spider when spider.IsPoisonous + => $"The {spider.Name} spider is poisonous. Run!", + null + => "The animal is null.", + _ + => $"The animal named {animal.Name} is a {animal.GetType().Name}." + }; + WriteLine($"switch expression: {message}"); +}