Listing updates based on technical reviews.
MODIFY
src/Chapter08/Listing08.12.DerivingOneInterfaceFromAnother.cs
src/Chapter08/Listing08.12.DerivingOneInterfaceFromAnother.cs
interface IDistributedSettingsProvider : ISettingsProvider
{
/// <summary>
- /// Get the settings for a particular machine
+ /// Get the settings for a particular URI
/// </summary>
- /// <param name="machineName">
- /// The machine name the setting is related to</param>
+ /// <param name="uri">
+ /// The URI name the setting is related to</param>
/// <param name="name">The name of the setting</param>
/// <param name="defaultValue">
/// The value returned if the setting is not found</param>
/// <returns>The specified setting</returns>
string GetSetting(
- string machineName, string name, string defaultValue);
+ string uri, string name, string defaultValue);
/// <summary>
- /// Set the settings for a particular machine
+ /// Set the settings for a particular URI
/// </summary>
- /// <param name="machineName">
- /// The machine name the setting is related to</param>
+ /// <param name="uri">
+ /// The URI name the setting is related to</param>
/// <param name="name">The name of the setting</param>
/// <param name="value">The value to be persisted</param>
/// <returns>The specified setting</returns>
void SetSetting(
- string machineName, string name, string value);
+ string uri, string name, string value);
}
}

MODIFY
src/Chapter08/Table08.01.DefaultImplementedInterfaceMembers.cs
src/Chapter08/Table08.01.DefaultImplementedInterfaceMembers.cs
@@ -124,6 +124,51 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter08.Table08_01
}
// 8.
+ namespace PrivateProtectedAccessModifiers
+ {
+ class Program
+ {
+ static void Main()
+ {
+ IPerson? person = null;
+ // Non-deriving classes cannot call
+ // private protected member.
+ // person?.GetName();
+ Console.WriteLine(person);
+ }
+ }
+ public interface IPerson
+ {
+ string FirstName { get; }
+ string LastName { get; }
+ string Name => GetName();
+ private protected string GetName() =>
+ $"{FirstName} {LastName}";
+ }
+ public interface IEmployee: IPerson
+ {
+ int EmpoyeeId => GetName().GetHashCode();
+ }
+ public class Person : IPerson
+ {
+ 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; }
+
+ // private protected interface members
+ // are not accessible in derived classes.
+
+ // public int PersonTitle => GetName().ToUpper();
+ }
+ }
+
+ // 9.
namespace VirtualMembers
{
public interface IPerson
@@ -138,7 +183,7 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter08.Table08_01
}
}
- // 9.
+ // 10.
namespace SealedMembers
{
public interface IWorkflowActivity
@@ -171,7 +216,7 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter08.Table08_01
}
}
- // 10.
+ // 11.
namespace AbstractMembers
{
public interface IPerson
@@ -188,7 +233,7 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter08.Table08_01
}
}
- // 11.
+ // 12.
namespace PartialMembers
{
public partial interface IThing

ADD
src/Chapter09.Tests/Listing09.05.cs
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter09.Listing09_05.Tests
+{
+ [TestClass]
+ public class ProgramTests
+ {
+
+ [TestMethod]
+ [ExpectedException(typeof(InvalidCastException))]
+ public void AddToArrayIndexWithoutCasing()
+ {
+ string expected = "<<7>>";
+
+ IntelliTect.TestTools.Console.ConsoleAssert.Expect(
+ expected, Program.Main);
+ }
+
+ [TestMethod]
+ public void AddToArrayWithCasting()
+ {
+ const string OutputFormatString = @"Enter a number between 2 and 1000: <<{0}>>0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141,";
+
+ string expected = string.Format(OutputFormatString, 42);
+
+ IntelliTect.TestTools.Console.ConsoleAssert.Expect(
+ expected, Program.Main);
+ }
+ }
+}

MODIFY
src/Chapter10/Listing10.05.OverridingEquals.cs
src/Chapter10/Listing10.05.OverridingEquals.cs
@@ -45,11 +45,14 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter10.Listing10_05
{
return false;
}
- // STEP 3: Equivalent data types
+ // STEP 2: Equivalent data types
+ // can be avoided if type is sealed
if (this.GetType() != obj.GetType())
{
return false;
}
+
+ // STEP 3: Invoked strongly type helper version of Equals()
return Equals((Coordinate)obj);
}
@@ -62,13 +65,6 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter10.Listing10_05
// return false;
// }
- // STEP 2: Check for ReferenceEquals if this
- // is a reference type.
- // if ( ReferenceEquals(this, obj))
- // {
- // return true;
- // }
-
// STEP 4: Possibly check for equivalent hash codes.
// if (this.GetHashCode() != obj.GetHashCode())
// {
@@ -78,10 +74,10 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter10.Listing10_05
// STEP 5: Check base.Equals if base overrides Equals().
// System.Diagnostics.Debug.Assert(
// base.GetType() != typeof(object) );
- // if ( !base.Equals(obj) )
- // {
- // return false;
- // }
+ if (!base.Equals(obj))
+ {
+ return false;
+ }
// STEP 6: Compare identifying fields for equality
// using an overload of Equals on Longitude
@@ -90,12 +86,10 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter10.Listing10_05
}
// STEP 7: Override GetHashCode
- public override int GetHashCode()
- {
- int hashCode = Longitude.GetHashCode();
- hashCode ^= Latitude.GetHashCode(); // Xor (eXclusive OR)
- return hashCode;
- }
+ public override int GetHashCode() =>
+ HashCode.Combine(Longitude.GetHashCode(), Latitude.GetHashCode());
+
+ // STEP 8: Override the ==/!= operators
public static bool operator ==(
Coordinate leftHandSide,
Coordinate rightHandSide)
@@ -103,6 +97,7 @@ namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter10.Listing10_05
return (leftHandSide.Equals(rightHandSide));
}
+ // STEP 8: Override the ==/!= operators
public static bool operator !=(
Coordinate leftHandSide,
Coordinate rightHandSide)

MODIFY
src/Chapter11/Listing11.02.CatchingDifferentExceptionTypes.cs
src/Chapter11/Listing11.02.CatchingDifferentExceptionTypes.cs
// Handle Win32Exception where
// ErrorCode is 42
}
- catch(NullReferenceException exception)
- {
- // Handle NullReferenceException
- }
catch(ArgumentException exception)
{
// Handle ArgumentException

MODIFY
src/Chapter11/Listing11.05.DefiningASerializableException.cs
src/Chapter11/Listing11.05.DefiningASerializableException.cs
-//namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter11.Listing11_06
-//{
-// using System;
-// using System.Runtime.Serialization;
+namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter11.Listing11_05
+{
+ using System;
+ using System.Runtime.Serialization;
-// // Supporting serialization via an attribute
-// [Serializable]
-// class DatabaseException : System.ApplicationException
-// {
-// // ...
+ // Supporting serialization via an attribute
+ [Serializable]
+ class DatabaseException : System.Exception
+ {
+ // ...
-// // Used for deserialization of exceptions
-// public DatabaseException(
-// SerializationInfo serializationInfo,
-// StreamingContext context)
-// {
-// //...
-// }
-// }
-//}
+ // Used for deserialization of exceptions
+ public DatabaseException(
+ SerializationInfo serializationInfo,
+ StreamingContext context) : base(serializationInfo, context)
+ {
+ //...
+ }
+ }
+}

Listing updates based on technical reviews.