Added parameter validation listings to Chapter 5
MODIFY
src/Chapter05.Tests/Listing05.31.Tests.cs
src/Chapter05.Tests/Listing05.31.Tests.cs
@@ -3,29 +3,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_31.Tests;
[TestClass]
-public class LeveragingTryParseTests
+public class ProgramTests
{
- [TestMethod]
- public void Main_InputNameAndAge35_AgeProperlyParsed()
- {
- const string expected =
-@"Enter your first name: <<Inigo
->>Enter your age: <<36
->>Hi Inigo! You are 432 months old.";
-
- IntelliTect.TestTools.Console.ConsoleAssert.Expect(expected,
- LeveragingTryParse.Main);
- }
-
- [TestMethod]
- public void Main_InputNameAndAgeThirtyFive_AgeNotParsed()
- {
- const string expected =
-@"Enter your first name: <<Inigo
->>Enter your age: <<ThirtyFive
->>The age entered, ThirtyFive, is not valid.";
-
- IntelliTect.TestTools.Console.ConsoleAssert.Expect(
- expected, LeveragingTryParse.Main);
- }
}

ADD
src/Chapter05.Tests/Listing05.32.Tests.cs
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_32.Tests;
+
+[TestClass]
+public class ProgramTests
+{
+
+}

ADD
src/Chapter05.Tests/Listing05.33.Tests.cs
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_33.Tests;
+
+[TestClass]
+public class ProgramTests
+{
+
+}

ADD
src/Chapter05.Tests/Listing05.34.Tests.cs
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_34.Tests;
+
+[TestClass]
+public class LeveragingTryParseTests
+{
+ [TestMethod]
+ public void Main_InputNameAndAge35_AgeProperlyParsed()
+ {
+ const string expected =
+@"Enter your first name: <<Inigo
+>>Enter your age: <<36
+>>Hi Inigo! You are 432 months old.";
+
+ IntelliTect.TestTools.Console.ConsoleAssert.Expect(expected,
+ LeveragingTryParse.Main);
+ }
+
+ [TestMethod]
+ public void Main_InputNameAndAgeThirtyFive_AgeNotParsed()
+ {
+ const string expected =
+@"Enter your first name: <<Inigo
+>>Enter your age: <<ThirtyFive
+>>The age entered, ThirtyFive, is not valid.";
+
+ IntelliTect.TestTools.Console.ConsoleAssert.Expect(
+ expected, LeveragingTryParse.Main);
+ }
+}

MODIFY
src/Chapter05/Listing05.15.PassingCommandLineArgumentsToMain.cs
src/Chapter05/Listing05.15.PassingCommandLineArgumentsToMain.cs
@@ -9,10 +9,9 @@ public class Program
{
#region HIGHLIGHT
int result;
- switch(args.Length)
+ if(args?.Length != 2 )
#endregion HIGHLIGHT
{
- default:
// Exactly two arguments must be specified; give an error
Console.WriteLine(
"ERROR: You must specify the "
@@ -20,8 +19,9 @@ public class Program
Console.WriteLine(
"Usage: Downloader.exe <URL> <TargetFileName>");
result = 1;
- break;
- case 2:
+ }
+ else
+ {
#region HIGHLIGHT
string urlString = args[0];
string fileName = args[1];
@@ -33,9 +33,6 @@ public class Program
File.WriteAllBytes(fileName, response);
Console.WriteLine($"Downloaded '{ fileName }' from '{ urlString }'.");
result = 0;
- #region HIGHLIGHT
- break;
- #endregion HIGHLIGHT
}
#region HIGHLIGHT
return result;

MODIFY
src/Chapter05/Listing05.21.CountingLinesGivenADirectory.cs
src/Chapter05/Listing05.21.CountingLinesGivenADirectory.cs
@@ -49,6 +49,8 @@ public static class LineCounter
{
string? line;
int lineCount = 0;
+ // This can be improved with a using statement
+ // which is not yet described.
FileStream stream =
new FileStream(file, FileMode.Open);
StreamReader reader = new StreamReader(stream);

MODIFY
src/Chapter05/Listing05.22.CountingLinesUsingOverloading.cs
src/Chapter05/Listing05.22.CountingLinesUsingOverloading.cs
@@ -70,6 +70,8 @@ public static class LineCounter
{
int lineCount = 0;
string? line;
+ // This can be improved with a using statement
+ // which is not yet described.
FileStream stream =
new FileStream(file, FileMode.Open);
StreamReader reader = new StreamReader(stream);

ADD
src/Chapter05/Listing05.31.ParameterValidationThrowingArgumentNullException.cs
+#pragma warning disable IDE0059 // Unnecessary assignment of a value
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_31;
+
+public class Program
+{
+ public static void Main()
+ {
+ DownloadSSL(null!, null!);
+ }
+
+ public static void DownloadSSL(string httpsUrl, string fileName)
+ {
+ #region INCLUDE
+ httpsUrl = httpsUrl ??
+ throw new ArgumentNullException(nameof(httpsUrl));
+ fileName = fileName??
+ throw new ArgumentNullException(nameof(fileName));
+
+
+ // ...
+ #endregion INCLUDE
+ }
+}

ADD
src/Chapter05/Listing05.32.ParameterValidationWithArgumentException.ThrowIfNull.cs
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_32;
+
+public class Program
+{
+ public static void Main()
+ {
+ DownloadSSL(null!, null!);
+ }
+
+ public static void DownloadSSL(string httpsUrl, string fileName)
+ {
+#if !NET7_0_OR_GREATER
+ httpsUrl = httpsUrl?.Trim() ??
+ throw new ArgumentNullException(nameof(httpsUrl));
+ fileName = fileName ??
+ throw new ArgumentNullException(nameof(fileName));
+ if (fileName.Trim().Length == 0)
+ {
+ throw new ArgumentException(
+ $"{nameof(fileName)} cannot be empty or only whitespace");
+ }
+#else
+ #region INCLUDE
+ ArgumentNullException.ThrowIfNull(httpsUrl);
+ ArgumentNullException.ThrowIfNull(fileName);
+
+ // ...
+ #endregion INCLUDE
+#endif
+
+ }
+}

ADD
src/Chapter05/Listing05.33.CustomParameterValidation.cs
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_33;
+
+#region INCLUDE
+public class Program
+{
+ #region HIGHLIGHT
+ public static int Main(string[] args)
+ #endregion HIGHLIGHT
+ {
+ #region HIGHLIGHT
+ int result = 0;
+ #endregion HIGHLIGHT
+ if(args.Length != 2 )
+ {
+ // Exactly two arguments must be specified; give an error
+ Console.WriteLine(
+ "ERROR: You must specify the "
+ + "URL and the file name");
+ Console.WriteLine(
+ "Usage: Downloader.exe <URL> <TargetFileName>");
+ result = 1;
+ }
+ else
+ {
+ DownloadSSL(args[0], args[1]);
+ }
+ return result;
+ }
+
+private static void DownloadSSL(string httpsUrl, string fileName)
+{
+#if !NET7_0_OR_GREATER
+ httpsUrl = httpsUrl?.Trim() ??
+ throw new ArgumentNullException(nameof(httpsUrl));
+ fileName = fileName ??
+ throw new ArgumentNullException(nameof(fileName));
+ if (fileName.Trim().Length == 0)
+ {
+ throw new ArgumentException(
+ $"{nameof(fileName)} cannot be empty or only whitespace");
+ }
+#else
+ ArgumentException.ThrowIfNullOrEmpty(httpsUrl.Trim());
+ ArgumentException.ThrowIfNullOrEmpty(fileName?.Trim());
+#endif
+
+ if (!httpsUrl.ToUpper().StartsWith("HTTPS"))
+ {
+ throw new ArgumentException("URL must start with 'HTTPS'.");
+ }
+
+ HttpClient client = new();
+ byte[] response =
+ client.GetByteArrayAsync(httpsUrl).Result;
+ client.Dispose();
+ File.WriteAllBytes(fileName!, response);
+ Console.WriteLine($"Downloaded '{fileName}' from '{httpsUrl}'.");
+}
+}
+#endregion INCLUDE

RENAME
src/Chapter05/Listing05.31.TryCatch.cs
src/Chapter05/Listing05.34.TryCatch.cs
-namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_31;
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter05.Listing05_34;
public class LeveragingTryParse
{

Added parameter validation listings to Chapter 5 (#407)