Completed listings for pattern matching.
RENAME
src/Chapter07.Tests/Listing07.32.SwitchWithPatternMatching.Tests.cs
src/Chapter07.Tests/Listing07.30.SwitchWithPatternMatching.Tests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
-namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_32.Tests;
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_30.Tests;
[TestClass]
public class ProgramTests

RENAME
src/Chapter07.Tests/Listing07.30.RecursivePatternMatching.Tests.cs
src/Chapter07.Tests/Listing07.31.RecursivePatternMatching.Tests.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
-namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_30.Tests;
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_31.Tests;
[TestClass]
public class ProgramTests

ADD
src/Chapter07.Tests/Listing07.32.Tests.cs
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_32.Tests;
+
+[TestClass]
+public class ProgramTests
+{
+
+ [TestMethod]
+ [DataRow("help")]
+ [DataRow("h")]
+ [DataRow("?")]
+ [DataRow("<invalid>")]
+ public void ParseHelpCommand(string command)
+ {
+ foreach (string item in PrefixCommands(command))
+ {
+ command = $"{item}";
+ IntelliTect.TestTools.Console.ConsoleAssert.Expect(
+ "Command Help...", () => Program.Main(command));
+ }
+ }
+
+ [TestMethod]
+ [DataRow("cat", @"..\SampleFile.txt")]
+ [DataRow("c", @"..\SampleFile.txt")]
+ public void ParseCatCommand(string command, string fileName)
+ {
+ foreach (string item in PrefixCommands(command))
+ {
+ command = $"{item}";
+ IntelliTect.TestTools.Console.ConsoleAssert.Expect(
+ $"Catalog '{fileName}'...", () => Program.Main(command, fileName));
+ }
+ }
+
+
+ [TestMethod]
+ [DataRow("copy", @"..\source.txt", @"..\target.txt")]
+ public void ParseCopyCommand(string command, string sourceFile, string targetFile)
+ {
+ foreach (string item in PrefixCommands(command))
+ {
+ command = $"{item}";
+ IntelliTect.TestTools.Console.ConsoleAssert.Expect(
+ $"Copy '{sourceFile}' '{targetFile}'...", () => Program.Main(command, sourceFile, targetFile));
+ }
+ }
+
+ private static List<string> PrefixCommands(string command)
+ {
+ List<string> commands = new();
+
+ string[] shortPrefix = new[] { "/", "-" };
+
+ if (command.Length == 1)
+ {
+ foreach (string item in shortPrefix)
+ {
+ commands.Add($"{item}{command}");
+ }
+ }
+ else
+ {
+ commands.Add($"--{command}");
+ }
+ return commands;
+ }
+
+
+}

RENAME
src/Chapter07/Listing07.32.SwitchWithPatternMatching.cs
src/Chapter07/Listing07.30.SwitchWithPatternMatching.cs
-namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_32;
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_30;
public class Program
{
@@ -23,7 +23,7 @@ public class Program
// preferable but not covered until Chapter 12.
((int Year, int Month, int Day)?) null,
_ => null
- } is { } date ? string.Format(
+ } is (int, int, int) date ? string.Format(
compositFormatString, date.Year, date.Month, date.Day) : null;
#endregion INCLUDE
}

DELETE
src/Chapter07/Listing07.31.PropertyPatternMatching.cs
-namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_31;
-
-public class Person
-{
- public Person(string firstName, string lastName)
- {
- FirstName = firstName ??
- throw new ArgumentNullException(nameof(firstName));
- LastName = lastName ??
- throw new ArgumentNullException(nameof(lastName));
- }
- public string FirstName { get; }
- public string LastName { get; }
-
- public void Deconstruct(out string firstName, out string lastName) =>
- (firstName, lastName) = (FirstName, LastName);
-}
-public class Program
-{
- public static void Main()
- {
- #region INCLUDE
- //// ...
- //(int x, int y) point = (42, -42);
-
- //string quadrant = point switch
- //{
- // (>=0, >=0) => "Quadrant 1",
- // (>0, <0) => "Quadrant 2",
- // (<0, <0) => "Quadrant 3",
- // (<0, >0) => "Quadrant 4",
- //};
-
-
-
-
- // ...
- #endregion INCLUDE
- }
-
-
- public static bool TryGetPhoneButton(char character, out char? button)
- {
- bool success = true;
- switch (char.ToLower(character))
- {
- case '1':
- button = '1';
- break;
- case >='a' and <='c' or '2':
- button = '2';
- break;
- case >='d' and <='f' or '3':
- button = '3';
- break;
- case >='g' and <='i' or '4':
- button = '4';
- break;
- case >='j' and <='l' or '5':
- button = '5';
- break;
- case >='m' and <='o' or '6':
- button = '6';
- break;
- case >='p' and <='s' or '7':
- button = '7';
- break;
- case >='t' and <='v' or '8':
- button = '8';
- break;
- case >='w' and <='z' or '9':
- button = '9';
- break;
- case '+':
- button = '0';
- break;
- case '-':
- button = '-';
- break;
- default:
- // Set the button to indicate an invalid value
- button = '_';
- success = false;
- break;
- }
- return success;
- }
-
- public static char GetPhoneButton(char character) =>
- char.ToLower(character) switch
- {
- '1' => '1',
- >='a' and <='c' or '2' => '2',
- >='d' and <='f' or '3' => '3',
- >='g' and <='i' or '4' => '4',
- >='j' and <='l' or '5' => '5',
- >='m' and <='o' or '6' => '6',
- >='p' and <='s' or '7' => '7',
- >='t' and <='v' or '8' => '8',
- >='w' and <='z' or '9' => '9',
- '+' => '0',
- '-' => '-',
- // Set the button to indicate an invalid value
- _ => '_',
- };
-}
-

RENAME
src/Chapter07/Listing07.30.RecursivePatternMatching.cs
src/Chapter07/Listing07.31.RecursivePatternMatching.cs
-namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_30;
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_31;
public class Person
{

ADD
src/Chapter07/Listing07.32.ListPatternMatching.cs
+using System.Diagnostics;
+
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter07.Listing07_32;
+
+#region INCLUDE
+
+public class Program
+{
+ public static void Main(params string[] args)
+ {
+ // For simplicitly, commands are assumed
+ // to all be lower case.
+
+ // The first argument is the command and is
+ // identified by a '/', '-', or '--' prefix.
+
+ switch (args)
+ {
+ case ["--help" or ['/' or '-', 'h' or '?']]:
+ // e.g. /?, -?, /h, -h, --help
+ DisplayHelp();
+ break;
+ case [ ['/' or '-', char command] /*command*/, ..]:
+ // Command begins with '/', '-' and has 0 ore more arguments.
+ if(!ExecuteCommand($"{command}", args[1..]))
+ {
+ DisplayHelp();
+ }
+ break;
+ case [ ['-', '-', ..] command, ..]:
+ // Command begins with "--" and has 0 ore more arguments.
+ if(!ExecuteCommand(command[2..], args[1..]))
+ {
+ DisplayHelp();
+ }
+ break;
+
+ // The following cases are redundant with default
+ // but provided for demonstration purposes.
+ case []:
+ // No command line arguments
+
+ default:
+ DisplayHelp();
+ break;
+ }
+ }
+
+ static bool ExecuteCommand(string command, string[] args) =>
+ (command, args) switch
+ {
+ ("cat" or "c", [string fileName]) =>
+ CatalogFile(fileName),
+ ("copy", [string sourceFile, string targetFile]) =>
+ CopyFile(sourceFile, targetFile),
+ _ => false
+ };
+
+
+ private static bool CopyFile(object sourceFile, string targetFile)
+ {
+ Console.WriteLine($"Copy '{sourceFile}' '{targetFile}'...");
+ return true;
+ }
+ #region EXCLUDE
+
+ private static bool CatalogFile(string fileName)
+ {
+ Console.WriteLine($"Catalog '{fileName}'...");
+ return true;
+ }
+
+
+
+
+ private static void DisplayHelp()
+ {
+ Console.WriteLine("Command Help...");
+ }
+ #endregion EXCLUDE
+}
+#endregion INCLUDE

Completed listings for pattern matching.