mirror of
https://github.com/markjprice/cs11dotnet7.git
synced 2025-12-06 05:32:03 +01:00
Add item for page 235
This commit is contained in:
parent
627003b8ba
commit
de9165c9e6
|
|
@ -4,7 +4,7 @@ If you find any mistakes in the seventh edition, *C# 11 and .NET 7 - Modern Cros
|
||||||
|
|
||||||
[**Errata** (42 items)](errata.md): Typos, tool user interface changes, or mistakes in code that would cause a compilation error that prevents a successful build.
|
[**Errata** (42 items)](errata.md): Typos, tool user interface changes, or mistakes in code that would cause a compilation error that prevents a successful build.
|
||||||
|
|
||||||
[**Improvements** (29 items)](improvements.md): Changes to text or code that would improve the content. These are optional.
|
[**Improvements** (30 items)](improvements.md): Changes to text or code that would improve the content. These are optional.
|
||||||
|
|
||||||
[**Common Errors** (3 items)](common-errors.md): These are some of the most common errors that a reader might encounter when trying to get code in book tasks to work, or when trying to write your own code.
|
[**Common Errors** (3 items)](common-errors.md): These are some of the most common errors that a reader might encounter when trying to get code in book tasks to work, or when trying to write your own code.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
**Improvements** (29 items)
|
**Improvements** (30 items)
|
||||||
|
|
||||||
If you have suggestions for improvements, then please [raise an issue in this repository](https://github.com/markjprice/cs11dotnet7/issues) or email me at markjprice (at) gmail.com.
|
If you have suggestions for improvements, then please [raise an issue in this repository](https://github.com/markjprice/cs11dotnet7/issues) or email me at markjprice (at) gmail.com.
|
||||||
|
|
||||||
|
|
@ -11,6 +11,7 @@ If you have suggestions for improvements, then please [raise an issue in this re
|
||||||
- [Page 161 - Using lambdas in function implementations](#page-161---using-lambdas-in-function-implementations)
|
- [Page 161 - Using lambdas in function implementations](#page-161---using-lambdas-in-function-implementations)
|
||||||
- [Page 179 - Reviewing project packages](#page-179---reviewing-project-packages)
|
- [Page 179 - Reviewing project packages](#page-179---reviewing-project-packages)
|
||||||
- [Page 200 - Talking about OOP](#page-200---talking-about-oop)
|
- [Page 200 - Talking about OOP](#page-200---talking-about-oop)
|
||||||
|
- [Page 235 - More about methods](#page-235---more-about-methods)
|
||||||
- [Page 237 - Implementing functionality using methods](#page-237---implementing-functionality-using-methods)
|
- [Page 237 - Implementing functionality using methods](#page-237---implementing-functionality-using-methods)
|
||||||
- [Page 241 - Defining flight passengers](#page-241---defining-flight-passengers)
|
- [Page 241 - Defining flight passengers](#page-241---defining-flight-passengers)
|
||||||
- [Page 251 - Setting up a class library and console application](#page-251---setting-up-a-class-library-and-console-application)
|
- [Page 251 - Setting up a class library and console application](#page-251---setting-up-a-class-library-and-console-application)
|
||||||
|
|
@ -235,6 +236,129 @@ interface ITheta { void M3() { } void M4(); }
|
||||||
class Iota : ITheta { void M4() { } }
|
class Iota : ITheta { void M4() { } }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Page 235 - More about methods
|
||||||
|
|
||||||
|
> Thanks to [cgwid](https://github.com/cgwid) for raising this [issue on 12 April 2023](https://github.com/markjprice/cs11dotnet7/issues/59).
|
||||||
|
|
||||||
|
In this section, we define some methods and operators so that two `Person` objects can get married and have babies. The example we model comes from the Bible story of Lamech and his two wives and their children. But the code I tell you to write does not allow Lamech to marry two women so later an exception is thrown when Lamech and his second wife try to make a baby.
|
||||||
|
|
||||||
|
cgwid suggested a solution in [the issue they raised](https://github.com/markjprice/cs11dotnet7/issues/59).
|
||||||
|
|
||||||
|
Here is my possible improvement. I might change it before using it in the next edition. We could use a `List<Person>` to store the zero, one or more people that a `Person` is married too. We could implement `Married` as a readonly property that calls the LINQ `Any` method to return `true` if there are any items in the `Spouses` list, as shown in the following code:
|
||||||
|
```cs
|
||||||
|
// Is this person married to anyone?
|
||||||
|
public bool Married => Spouses.Any();
|
||||||
|
|
||||||
|
// Allow multiple spouses.
|
||||||
|
public List<Person> Spouses = new();
|
||||||
|
```
|
||||||
|
|
||||||
|
Then we can implement the `static Marry` method by checking if the person is already in the list and then adding them if they are not, as shown in the following code:
|
||||||
|
```cs
|
||||||
|
// static method to marry
|
||||||
|
public static void Marry(Person p1, Person p2)
|
||||||
|
{
|
||||||
|
if (p1.Spouses.Contains(p2) || p2.Spouses.Contains(p1))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format("{0} is already married to {1}.",
|
||||||
|
arg0: p1.Name, arg1: p2.Name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p1.Spouses.Add(p2);
|
||||||
|
p2.Spouses.Add(p1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// instance method to marry
|
||||||
|
public void Marry(Person partner)
|
||||||
|
{
|
||||||
|
Marry(this, partner);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For convenience, we could create a method to output the number of and names of spouses of the current person, as shown in the following code:
|
||||||
|
```cs
|
||||||
|
public void OutputSpouses()
|
||||||
|
{
|
||||||
|
if (Married)
|
||||||
|
{
|
||||||
|
string term = Spouses.Count == 1 ? "person" : "people";
|
||||||
|
WriteLine($"{Name} is married to {Spouses.Count} {term}:");
|
||||||
|
foreach (Person spouse in Spouses)
|
||||||
|
{
|
||||||
|
WriteLine($" {spouse.Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteLine($"{Name} is not married.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
We would also need to change the `Procreate` method to check that the two people are married before allowing them to make a baby, as shown in the following code:
|
||||||
|
```cs
|
||||||
|
// static method to "multiply"
|
||||||
|
public static Person Procreate(Person p1, Person p2)
|
||||||
|
{
|
||||||
|
if (!p1.Spouses.Contains(p2))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format("{0} must be married to {1} to procreate with them.",
|
||||||
|
arg0: p1.Name, arg1: p2.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
Person baby = new()
|
||||||
|
{
|
||||||
|
Name = $"Baby of {p1.Name} and {p2.Name}",
|
||||||
|
DateOfBirth = DateTime.Now
|
||||||
|
};
|
||||||
|
|
||||||
|
p1.Children.Add(baby);
|
||||||
|
p2.Children.Add(baby);
|
||||||
|
|
||||||
|
return baby;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, we can call the `OutputSpouses` method in `Program.cs`, as shown in the following code:
|
||||||
|
```cs
|
||||||
|
// Implementing functionality using methods
|
||||||
|
Person lamech = new() { Name = "Lamech" };
|
||||||
|
Person adah = new() { Name = "Adah" };
|
||||||
|
Person zillah = new() { Name = "Zillah" };
|
||||||
|
|
||||||
|
lamech.Marry(adah);
|
||||||
|
// Person.Marry(zillah, lamech);
|
||||||
|
|
||||||
|
if (zillah + lamech)
|
||||||
|
{
|
||||||
|
WriteLine($"{zillah.Name} and {lamech.Name} successfully got married.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteLine($"{zillah.Name} and {lamech.Name} failed to marry.");
|
||||||
|
}
|
||||||
|
|
||||||
|
lamech.OutputSpouses();
|
||||||
|
adah.OutputSpouses();
|
||||||
|
zillah.OutputSpouses();
|
||||||
|
```
|
||||||
|
|
||||||
|
The output should look like this:
|
||||||
|
```
|
||||||
|
Zillah and Lamech successfully got married.
|
||||||
|
Lamech is married to 2 people:
|
||||||
|
Adah
|
||||||
|
Zillah
|
||||||
|
Adah is married to 1 person:
|
||||||
|
Lamech
|
||||||
|
Zillah is married to 1 person:
|
||||||
|
Lamech
|
||||||
|
```
|
||||||
|
|
||||||
# Page 237 - Implementing functionality using methods
|
# Page 237 - Implementing functionality using methods
|
||||||
|
|
||||||
> Thanks to [Masoud Nazari](https://github.com/MAS-OUD) for raising this [issue on 5 March 2023](https://github.com/markjprice/cs11dotnet7/issues/35).
|
> Thanks to [Masoud Nazari](https://github.com/MAS-OUD) for raising this [issue on 5 March 2023](https://github.com/markjprice/cs11dotnet7/issues/35).
|
||||||
|
|
|
||||||
|
|
@ -74,33 +74,59 @@ public partial class Person
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool married = false;
|
// Is this person married to anyone?
|
||||||
public bool Married => married;
|
public bool Married => Spouses.Any();
|
||||||
|
|
||||||
private Person? spouse = null;
|
// Allow multiple spouses.
|
||||||
public Person? Spouse => spouse;
|
public List<Person> Spouses = new();
|
||||||
|
|
||||||
// static method to marry
|
// static method to marry
|
||||||
public static void Marry(Person p1, Person p2)
|
public static void Marry(Person p1, Person p2)
|
||||||
{
|
{
|
||||||
p1.Marry(p2);
|
if (p1.Spouses.Contains(p2) || p2.Spouses.Contains(p1))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format("{0} is already married to {1}.",
|
||||||
|
arg0: p1.Name, arg1: p2.Name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p1.Spouses.Add(p2);
|
||||||
|
p2.Spouses.Add(p1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// instance method to marry
|
// instance method to marry
|
||||||
public void Marry(Person partner)
|
public void Marry(Person partner)
|
||||||
{
|
{
|
||||||
if (married) return;
|
Marry(this, partner);
|
||||||
spouse = partner;
|
}
|
||||||
married = true;
|
|
||||||
partner.Marry(this); // this is the current object
|
public void OutputSpouses()
|
||||||
|
{
|
||||||
|
if (Married)
|
||||||
|
{
|
||||||
|
string term = Spouses.Count == 1 ? "person" : "people";
|
||||||
|
WriteLine($"{Name} is married to {Spouses.Count} {term}:");
|
||||||
|
foreach (Person spouse in Spouses)
|
||||||
|
{
|
||||||
|
WriteLine($" {spouse.Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteLine($"{Name} is not married.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static method to "multiply"
|
// static method to "multiply"
|
||||||
public static Person Procreate(Person p1, Person p2)
|
public static Person Procreate(Person p1, Person p2)
|
||||||
{
|
{
|
||||||
if (p1.Spouse != p2)
|
if (!p1.Spouses.Contains(p2))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("You must be married to procreate.");
|
throw new ArgumentException(
|
||||||
|
string.Format("{0} must be married to {1} to procreate with them.",
|
||||||
|
arg0: p1.Name, arg1: p2.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
Person baby = new()
|
Person baby = new()
|
||||||
|
|
|
||||||
|
|
@ -211,14 +211,19 @@ Person zillah = new() { Name = "Zillah" };
|
||||||
|
|
||||||
lamech.Marry(adah);
|
lamech.Marry(adah);
|
||||||
// Person.Marry(zillah, lamech);
|
// Person.Marry(zillah, lamech);
|
||||||
|
|
||||||
if (zillah + lamech)
|
if (zillah + lamech)
|
||||||
{
|
{
|
||||||
WriteLine($"{zillah.Name} and {lamech.Name} successfully got married.");
|
WriteLine($"{zillah.Name} and {lamech.Name} successfully got married.");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteLine($"{zillah.Name} and {lamech.Name} failed to marry.");
|
||||||
|
}
|
||||||
|
|
||||||
WriteLine($"{lamech.Name} is married to {lamech.Spouse?.Name ?? "nobody"}");
|
lamech.OutputSpouses();
|
||||||
WriteLine($"{adah.Name} is married to {adah.Spouse?.Name ?? "nobody"}");
|
adah.OutputSpouses();
|
||||||
WriteLine($"{zillah.Name} is married to {zillah.Spouse?.Name ?? "nobody"}");
|
zillah.OutputSpouses();
|
||||||
|
|
||||||
// call instance method
|
// call instance method
|
||||||
Person baby1 = lamech.ProcreateWith(adah);
|
Person baby1 = lamech.ProcreateWith(adah);
|
||||||
|
|
@ -248,7 +253,7 @@ for (int i = 0; i < lamech.Children.Count; i++)
|
||||||
|
|
||||||
// Implementing functionality using local functions
|
// Implementing functionality using local functions
|
||||||
|
|
||||||
int number = -1; // change to -1 to make the exception handling code execute
|
int number = 6; // change to -1 to make the exception handling code execute
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -74,33 +74,59 @@ public partial class Person
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool married = false;
|
// Is this person married to anyone?
|
||||||
public bool Married => married;
|
public bool Married => Spouses.Any();
|
||||||
|
|
||||||
private Person? spouse = null;
|
// Allow multiple spouses.
|
||||||
public Person? Spouse => spouse;
|
public List<Person> Spouses = new();
|
||||||
|
|
||||||
// static method to marry
|
// static method to marry
|
||||||
public static void Marry(Person p1, Person p2)
|
public static void Marry(Person p1, Person p2)
|
||||||
{
|
{
|
||||||
p1.Marry(p2);
|
if (p1.Spouses.Contains(p2) || p2.Spouses.Contains(p1))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
string.Format("{0} is already married to {1}.",
|
||||||
|
arg0: p1.Name, arg1: p2.Name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p1.Spouses.Add(p2);
|
||||||
|
p2.Spouses.Add(p1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// instance method to marry
|
// instance method to marry
|
||||||
public void Marry(Person partner)
|
public void Marry(Person partner)
|
||||||
{
|
{
|
||||||
if (married) return;
|
Marry(this, partner);
|
||||||
spouse = partner;
|
}
|
||||||
married = true;
|
|
||||||
partner.Marry(this); // this is the current object
|
public void OutputSpouses()
|
||||||
|
{
|
||||||
|
if (Married)
|
||||||
|
{
|
||||||
|
string term = Spouses.Count == 1 ? "person" : "people";
|
||||||
|
WriteLine($"{Name} is married to {Spouses.Count} {term}:");
|
||||||
|
foreach (Person spouse in Spouses)
|
||||||
|
{
|
||||||
|
WriteLine($" {spouse.Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteLine($"{Name} is not married.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// static method to "multiply"
|
// static method to "multiply"
|
||||||
public static Person Procreate(Person p1, Person p2)
|
public static Person Procreate(Person p1, Person p2)
|
||||||
{
|
{
|
||||||
if (p1.Spouse != p2)
|
if (!p1.Spouses.Contains(p2))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("You must be married to procreate.");
|
throw new ArgumentException(
|
||||||
|
string.Format("{0} must be married to {1} to procreate with them.",
|
||||||
|
arg0: p1.Name, arg1: p2.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
Person baby = new()
|
Person baby = new()
|
||||||
|
|
|
||||||
|
|
@ -211,14 +211,19 @@ Person zillah = new() { Name = "Zillah" };
|
||||||
|
|
||||||
lamech.Marry(adah);
|
lamech.Marry(adah);
|
||||||
// Person.Marry(zillah, lamech);
|
// Person.Marry(zillah, lamech);
|
||||||
|
|
||||||
if (zillah + lamech)
|
if (zillah + lamech)
|
||||||
{
|
{
|
||||||
WriteLine($"{zillah.Name} and {lamech.Name} successfully got married.");
|
WriteLine($"{zillah.Name} and {lamech.Name} successfully got married.");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteLine($"{zillah.Name} and {lamech.Name} failed to marry.");
|
||||||
|
}
|
||||||
|
|
||||||
WriteLine($"{lamech.Name} is married to {lamech.Spouse?.Name ?? "nobody"}");
|
lamech.OutputSpouses();
|
||||||
WriteLine($"{adah.Name} is married to {adah.Spouse?.Name ?? "nobody"}");
|
adah.OutputSpouses();
|
||||||
WriteLine($"{zillah.Name} is married to {zillah.Spouse?.Name ?? "nobody"}");
|
zillah.OutputSpouses();
|
||||||
|
|
||||||
// call instance method
|
// call instance method
|
||||||
Person baby1 = lamech.ProcreateWith(adah);
|
Person baby1 = lamech.ProcreateWith(adah);
|
||||||
|
|
@ -248,7 +253,7 @@ for (int i = 0; i < lamech.Children.Count; i++)
|
||||||
|
|
||||||
// Implementing functionality using local functions
|
// Implementing functionality using local functions
|
||||||
|
|
||||||
int number = -1; // change to -1 to make the exception handling code execute
|
int number = 6; // change to -1 to make the exception handling code execute
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue