Initial commit

This commit is contained in:
Mark J Price 2022-02-20 17:22:06 +00:00
parent 10cceacca6
commit bc96ccb183
22 changed files with 1283 additions and 0 deletions

View file

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32210.308
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PacktLibrary", "PacktLibrary\PacktLibrary.csproj", "{9E796C3B-6FF6-4E0A-8B6D-A591B6FD1308}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeopleApp", "PeopleApp\PeopleApp.csproj", "{DF7885A2-C9F1-4959-9D13-C72E5E77CCDA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9E796C3B-6FF6-4E0A-8B6D-A591B6FD1308}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9E796C3B-6FF6-4E0A-8B6D-A591B6FD1308}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E796C3B-6FF6-4E0A-8B6D-A591B6FD1308}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E796C3B-6FF6-4E0A-8B6D-A591B6FD1308}.Release|Any CPU.Build.0 = Release|Any CPU
{DF7885A2-C9F1-4959-9D13-C72E5E77CCDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF7885A2-C9F1-4959-9D13-C72E5E77CCDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF7885A2-C9F1-4959-9D13-C72E5E77CCDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF7885A2-C9F1-4959-9D13-C72E5E77CCDA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1A5D8950-33D6-47DC-B740-C193A5024C06}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,8 @@
namespace Packt.Shared;
public class BankAccount
{
public string? AccountName; // instance member
public decimal Balance; // instance member
public static decimal InterestRate; // shared member
}

View file

@ -0,0 +1,8 @@
namespace Packt.Shared;
public class Book
{
// required is not working in .NET 7 Preview 1
public /* required */ string? Isbn { get; set; }
public string? Title { get; set; }
}

View file

@ -0,0 +1,29 @@
namespace Packt.Shared;
public class BusinessClassPassenger
{
public override string ToString()
{
return "Business Class";
}
}
public class FirstClassPassenger
{
public int AirMiles { get; set; }
public override string ToString()
{
return $"First Class with {AirMiles:N0} air miles";
}
}
public class CoachClassPassenger
{
public double CarryOnKG { get; set; }
public override string ToString()
{
return $"Coach Class with {CarryOnKG:N2} KG carry on";
}
}

View file

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Using Include="System.Console" Static="true" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,103 @@
namespace Packt.Shared; // file-scoped namespace
public partial class Person : object
{
// fields
public string? Name;
public DateTime DateOfBirth;
public WondersOfTheAncientWorld FavoriteAncientWonder;
public WondersOfTheAncientWorld BucketList;
public List<Person> Children = new();
// constants
public const string Species = "Homo Sapiens";
// read-only fields
public readonly string HomePlanet = "Earth";
public readonly DateTime Instantiated;
// constructors
public Person()
{
// set default values for fields
// including read-only fields
Name = "Unknown";
Instantiated = DateTime.Now;
}
public Person(string initialName, string homePlanet)
{
Name = initialName;
HomePlanet = homePlanet;
Instantiated = DateTime.Now;
}
// methods
public void WriteToConsole()
{
WriteLine($"{Name} was born on a {DateOfBirth:dddd}.");
}
public string GetOrigin()
{
return $"{Name} was born on {HomePlanet}.";
}
public (string, int) GetFruit()
{
return ("Apples", 5);
}
public (string Name, int Number) GetNamedFruit()
{
return (Name: "Apples", Number: 5);
}
// deconstructors
public void Deconstruct(out string? name, out DateTime dob)
{
name = Name;
dob = DateOfBirth;
}
public void Deconstruct(out string? name,
out DateTime dob, out WondersOfTheAncientWorld fav)
{
name = Name;
dob = DateOfBirth;
fav = FavoriteAncientWonder;
}
public string SayHello()
{
return $"{Name} says 'Hello!'";
}
public string SayHello(string name)
{
return $"{Name} says 'Hello, {name}!'";
}
public string OptionalParameters(string command = "Run!",
double number = 0.0, bool active = true)
{
return string.Format(
format: "command is {0}, number is {1}, active is {2}",
arg0: command,
arg1: number,
arg2: active);
}
public void PassingParameters(int x, ref int y, out int z)
{
// out parameters cannot have a default
// AND must be initialized inside the method
z = 99;
// increment each parameter
x++;
y++;
z++;
}
}

View file

@ -0,0 +1,153 @@
namespace Packt.Shared;
// this file simulates an autogenerated class
public partial class Person
{
// a readonly property defined using C# 1 - 5 syntax
public string Origin
{
get
{
return string.Format("{0} was born on {1}",
arg0: Name, arg1: HomePlanet);
}
}
// two readonly properties defined using C# 6+ lambda expression body syntax
public string Greeting => $"{Name} says 'Hello!'";
public int Age => DateTime.Today.Year - DateOfBirth.Year;
// a read-write property defined using C# 3.0 syntax
public string? FavoriteIceCream { get; set; } // auto-syntax
// a private field to store the property value
private string? favoritePrimaryColor;
// a public property to read and write to the field
public string? FavoritePrimaryColor
{
get
{
return favoritePrimaryColor;
}
set
{
switch (value?.ToLower())
{
case "red":
case "green":
case "blue":
favoritePrimaryColor = value;
break;
default:
throw new ArgumentException(
$"{value} is not a primary color. " +
"Choose from: red, green, blue.");
}
}
}
// indexers
public Person this[int index]
{
get
{
return Children[index]; // pass on to the List<T> indexer
}
set
{
Children[index] = value;
}
}
public Person this[string name]
{
get
{
return Children.Find(p => p.Name == name);
}
set
{
Person found = Children.Find(p => p.Name == name);
if (found is not null) found = value;
}
}
private bool married = false;
public bool Married => married;
private Person? spouse = null;
public Person? Spouse => spouse;
// static method to marry
public static void Marry(Person p1, Person p2)
{
p1.Marry(p2);
}
// instance method to marry
public void Marry(Person partner)
{
if (married) return;
spouse = partner;
married = true;
partner.Marry(this);
}
// static method to "multiply"
public static Person Procreate(Person p1, Person p2)
{
if (p1.Spouse != p2)
{
throw new ArgumentException("You must be married to procreate.");
}
Person baby = new()
{
Name = $"Baby of {p1.Name} and {p2.Name}",
DateOfBirth = DateTime.Now
};
p1.Children.Add(baby);
p2.Children.Add(baby);
return baby;
}
// instance method to "multiply"
public Person ProcreateWith(Person partner)
{
return Procreate(this, partner);
}
// operator to "marry"
public static bool operator +(Person p1, Person p2)
{
Marry(p1, p2);
return p1.Married && p2.Married; // confirm they are both now married
}
// operator to "multiply"
public static Person operator *(Person p1, Person p2)
{
return Procreate(p1, p2);
}
// method with a local function
public static int Factorial(int number)
{
if (number < 0)
{
throw new ArgumentException(
$"{nameof(number)} cannot be less than zero.");
}
return localFactorial(number);
int localFactorial(int localNumber) // local function
{
if (localNumber == 0) return 1;
return localNumber * localFactorial(localNumber - 1);
}
}
}

View file

@ -0,0 +1,7 @@
namespace Packt.Shared;
public class ImmutablePerson
{
//public string? FirstName { get; init; }
//public string? LastName { get; init; }
}

View file

@ -0,0 +1,14 @@
namespace Packt.Shared;
[Flags]
public enum WondersOfTheAncientWorld : byte
{
None = 0b_0000_0000, // i.e. 0
GreatPyramidOfGiza = 0b_0000_0001, // i.e. 1
HangingGardensOfBabylon = 0b_0000_0010, // i.e. 2
StatueOfZeusAtOlympia = 0b_0000_0100, // i.e. 4
TempleOfArtemisAtEphesus = 0b_0000_1000, // i.e. 8
MausoleumAtHalicarnassus = 0b_0001_0000, // i.e. 16
ColossusOfRhodes = 0b_0010_0000, // i.e. 32
LighthouseOfAlexandria = 0b_0100_0000 // i.e. 64
}

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PacktLibrary\PacktLibrary.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="System.Console" Static="true" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,267 @@
using Packt.Shared;
Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.GetCultureInfo("en-GB");
// Person bob = new Person(); // C# 1.0 or later
// var bob = new Person(); // C# 3.0 or later
Person bob = new(); // C# 9.0 or later
WriteLine(bob.ToString());
bob.Name = "Bob Smith";
bob.DateOfBirth = new DateTime(1965, 12, 22); // C# 1.0 or later
WriteLine(format: "{0} was born on {1:dddd, d MMMM yyyy}",
arg0: bob.Name,
arg1: bob.DateOfBirth);
Person alice = new()
{
Name = "Alice Jones",
DateOfBirth = new(1998, 3, 7) // C# 9.0 or later
};
WriteLine(format: "{0} was born on {1:dd MMM yy}",
arg0: alice.Name,
arg1: alice.DateOfBirth);
bob.FavoriteAncientWonder = WondersOfTheAncientWorld.StatueOfZeusAtOlympia;
WriteLine(
format: "{0}'s favorite wonder is {1}. Its integer is {2}.",
arg0: bob.Name,
arg1: bob.FavoriteAncientWonder,
arg2: (int)bob.FavoriteAncientWonder);
bob.BucketList =
WondersOfTheAncientWorld.HangingGardensOfBabylon
| WondersOfTheAncientWorld.MausoleumAtHalicarnassus;
// bob.BucketList = (WondersOfTheAncientWorld)18;
WriteLine($"{bob.Name}'s bucket list is {bob.BucketList}");
bob.Children.Add(new Person { Name = "Alfred" }); // C# 3.0 and later
bob.Children.Add(new() { Name = "Zoe" }); // C# 9.0 and later
WriteLine($"{bob.Name} has {bob.Children.Count} children:");
for (int childIndex = 0; childIndex < bob.Children.Count; childIndex++)
{
WriteLine($"> {bob.Children[childIndex].Name}");
}
/*
foreach (Person child in bob.Children)
{
WriteLine($"> {child.Name}");
}
*/
BankAccount.InterestRate = 0.012M; // store a shared value
BankAccount jonesAccount = new();
jonesAccount.AccountName = "Mrs. Jones";
jonesAccount.Balance = 2400;
WriteLine(format: "{0} earned {1:C} interest.",
arg0: jonesAccount.AccountName,
arg1: jonesAccount.Balance * BankAccount.InterestRate);
BankAccount gerrierAccount = new();
gerrierAccount.AccountName = "Ms. Gerrier";
gerrierAccount.Balance = 98;
WriteLine(format: "{0} earned {1:C} interest.",
arg0: gerrierAccount.AccountName,
arg1: gerrierAccount.Balance * BankAccount.InterestRate);
WriteLine($"{bob.Name} is a {Person.Species}");
WriteLine($"{bob.Name} was born on {bob.HomePlanet}");
Person blankPerson = new();
WriteLine(format:
"{0} of {1} was created at {2:hh:mm:ss} on a {2:dddd}.",
arg0: blankPerson.Name,
arg1: blankPerson.HomePlanet,
arg2: blankPerson.Instantiated);
Person gunny = new(initialName: "Gunny", homePlanet: "Mars");
WriteLine(format:
"{0} of {1} was created at {2:hh:mm:ss} on a {2:dddd}.",
arg0: gunny.Name,
arg1: gunny.HomePlanet,
arg2: gunny.Instantiated);
bob.WriteToConsole();
WriteLine(bob.GetOrigin());
(string, int) fruit = bob.GetFruit();
WriteLine($"{fruit.Item1}, {fruit.Item2} there are.");
var fruitNamed = bob.GetNamedFruit();
WriteLine($"There are {fruitNamed.Number} {fruitNamed.Name}.");
var thing1 = ("Neville", 4);
WriteLine($"{thing1.Item1} has {thing1.Item2} children.");
var thing2 = (bob.Name, bob.Children.Count);
WriteLine($"{thing2.Name} has {thing2.Count} children.");
(string fruitName, int fruitNumber) = bob.GetFruit();
WriteLine($"Deconstructed: {fruitName}, {fruitNumber}");
// Deconstructing a Person
var (name1, dob1) = bob;
WriteLine($"Deconstructed: {name1}, {dob1}");
var (name2, dob2, fav2) = bob;
WriteLine($"Deconstructed: {name2}, {dob2}, {fav2}");
WriteLine(bob.SayHello());
WriteLine(bob.SayHello("Emily"));
WriteLine(bob.OptionalParameters());
WriteLine(bob.OptionalParameters("Jump!", 98.5));
WriteLine(bob.OptionalParameters(number: 52.7, command: "Hide!"));
WriteLine(bob.OptionalParameters("Poke!", active: false));
int a = 10;
int b = 20;
int c = 30;
WriteLine($"Before: a = {a}, b = {b}, c = {c}");
bob.PassingParameters(a, ref b, out c);
WriteLine($"After: a = {a}, b = {b}, c = {c}");
int d = 10;
int e = 20;
WriteLine($"Before: d = {d}, e = {e}, f doesn't exist yet!");
// simplified C# 7.0 or later syntax for the out parameter
bob.PassingParameters(d, ref e, out int f);
WriteLine($"After: d = {d}, e = {e}, f = {f}");
Person sam = new()
{
Name = "Sam",
DateOfBirth = new(1969, 6, 25)
};
WriteLine(sam.Origin);
WriteLine(sam.Greeting);
WriteLine(sam.Age);
sam.FavoriteIceCream = "Chocolate Fudge";
WriteLine($"Sam's favorite ice-cream flavor is {sam.FavoriteIceCream}.");
sam.FavoritePrimaryColor = "Red";
WriteLine($"Sam's favorite primary color is {sam.FavoritePrimaryColor}.");
Book book = new();
book.Title = "C# 11 and .NET 7 - Modern Cross-Platform Development";
sam.Children.Add(new() { Name = "Charlie", DateOfBirth = new(2010, 3, 18) });
sam.Children.Add(new() { Name = "Ella", DateOfBirth = new(2020, 12, 24) });
// get using Children list
WriteLine($"Sam's first child is {sam.Children[0].Name}.");
WriteLine($"Sam's second child is {sam.Children[1].Name}.");
// get using integer position indexer
WriteLine($"Sam's first child is {sam[0].Name}.");
WriteLine($"Sam's second child is {sam[1].Name}.");
// get using name indexer
WriteLine($"Sam's child named Ella is {sam["Ella"].Age} years old.");
// 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.");
}
WriteLine($"{lamech.Name} is married to {lamech.Spouse?.Name ?? "nobody"}");
WriteLine($"{adah.Name} is married to {adah.Spouse?.Name ?? "nobody"}");
WriteLine($"{zillah.Name} is married to {zillah.Spouse?.Name ?? "nobody"}");
// call instance method
Person baby1 = lamech.ProcreateWith(adah);
baby1.Name = "Jabal";
WriteLine($"{baby1.Name} was born on {baby1.DateOfBirth}");
// call static method
Person baby2 = Person.Procreate(zillah, lamech);
baby2.Name = "Tubalcain";
// use operator to "multiply"
Person baby3 = lamech * adah;
baby3.Name = "Jubal";
Person baby4 = zillah * lamech;
baby4.Name = "Naamah";
WriteLine($"{lamech.Name} has {lamech.Children.Count} children.");
WriteLine($"{adah.Name} has {adah.Children.Count} children.");
WriteLine($"{zillah.Name} has {zillah.Children.Count} children.");
for (int i = 0; i < lamech.Children.Count; i++)
{
WriteLine(format: "{0}'s child #{1} is named \"{2}\".",
arg0: lamech.Name, arg1: i, arg2: lamech[i].Name);
}
// Implementing functionality using local functions
WriteLine($"5! is {Person.Factorial(5)}");
// Pattern matching with objects
object[] passengers = {
new FirstClassPassenger { AirMiles = 1_419 },
new FirstClassPassenger { AirMiles = 16_562 },
new BusinessClassPassenger(),
new CoachClassPassenger { CarryOnKG = 25.7 },
new CoachClassPassenger { CarryOnKG = 0 },
};
foreach (object passenger in passengers)
{
decimal flightCost = passenger switch
{
/* C# 8 syntax
FirstClassPassenger p when p.AirMiles > 35000 => 1500M,
FirstClassPassenger p when p.AirMiles > 15000 => 1750M,
FirstClassPassenger => 2000M, */
// C# 9 or later syntax
FirstClassPassenger p => p.AirMiles switch
{
> 35000 => 1500M,
> 15000 => 1750M,
_ => 2000M
},
BusinessClassPassenger _ => 1000M,
CoachClassPassenger p when p.CarryOnKG < 10.0 => 500M,
CoachClassPassenger _ => 650M,
_ => 800M
};
WriteLine($"Flight costs {flightCost:C} for {passenger}");
}
//ImmutablePerson jeff = new()
//{
// FirstName = "Jeff",
// LastName = "Winger"
//};
//jeff.FirstName = "Geoff";

View file

@ -0,0 +1,10 @@
{
"folders": [
{
"path": "PacktLibrary"
},
{
"path": "PeopleApp"
}
]
}

View file

@ -0,0 +1,8 @@
namespace Packt.Shared;
public class BankAccount
{
public string? AccountName; // instance member
public decimal Balance; // instance member
public static decimal InterestRate; // shared member
}

View file

@ -0,0 +1,8 @@
namespace Packt.Shared;
public class Book
{
// required is not working in .NET 7 Preview 1
public /* required */ string? Isbn { get; set; }
public string? Title { get; set; }
}

View file

@ -0,0 +1,29 @@
namespace Packt.Shared;
public class BusinessClassPassenger
{
public override string ToString()
{
return "Business Class";
}
}
public class FirstClassPassenger
{
public int AirMiles { get; set; }
public override string ToString()
{
return $"First Class with {AirMiles:N0} air miles";
}
}
public class CoachClassPassenger
{
public double CarryOnKG { get; set; }
public override string ToString()
{
return $"Coach Class with {CarryOnKG:N2} KG carry on";
}
}

View file

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>10</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Using Include="System.Console" Static="true" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,103 @@
namespace Packt.Shared; // file-scoped namespace
public partial class Person : object
{
// fields
public string? Name;
public DateTime DateOfBirth;
public WondersOfTheAncientWorld FavoriteAncientWonder;
public WondersOfTheAncientWorld BucketList;
public List<Person> Children = new();
// constants
public const string Species = "Homo Sapiens";
// read-only fields
public readonly string HomePlanet = "Earth";
public readonly DateTime Instantiated;
// constructors
public Person()
{
// set default values for fields
// including read-only fields
Name = "Unknown";
Instantiated = DateTime.Now;
}
public Person(string initialName, string homePlanet)
{
Name = initialName;
HomePlanet = homePlanet;
Instantiated = DateTime.Now;
}
// methods
public void WriteToConsole()
{
WriteLine($"{Name} was born on a {DateOfBirth:dddd}.");
}
public string GetOrigin()
{
return $"{Name} was born on {HomePlanet}.";
}
public (string, int) GetFruit()
{
return ("Apples", 5);
}
public (string Name, int Number) GetNamedFruit()
{
return (Name: "Apples", Number: 5);
}
// deconstructors
public void Deconstruct(out string? name, out DateTime dob)
{
name = Name;
dob = DateOfBirth;
}
public void Deconstruct(out string? name,
out DateTime dob, out WondersOfTheAncientWorld fav)
{
name = Name;
dob = DateOfBirth;
fav = FavoriteAncientWonder;
}
public string SayHello()
{
return $"{Name} says 'Hello!'";
}
public string SayHello(string name)
{
return $"{Name} says 'Hello, {name}!'";
}
public string OptionalParameters(string command = "Run!",
double number = 0.0, bool active = true)
{
return string.Format(
format: "command is {0}, number is {1}, active is {2}",
arg0: command,
arg1: number,
arg2: active);
}
public void PassingParameters(int x, ref int y, out int z)
{
// out parameters cannot have a default
// AND must be initialized inside the method
z = 99;
// increment each parameter
x++;
y++;
z++;
}
}

View file

@ -0,0 +1,153 @@
namespace Packt.Shared;
// this file simulates an autogenerated class
public partial class Person
{
// a readonly property defined using C# 1 - 5 syntax
public string Origin
{
get
{
return string.Format("{0} was born on {1}",
arg0: Name, arg1: HomePlanet);
}
}
// two readonly properties defined using C# 6+ lambda expression body syntax
public string Greeting => $"{Name} says 'Hello!'";
public int Age => DateTime.Today.Year - DateOfBirth.Year;
// a read-write property defined using C# 3.0 syntax
public string? FavoriteIceCream { get; set; } // auto-syntax
// a private field to store the property value
private string? favoritePrimaryColor;
// a public property to read and write to the field
public string? FavoritePrimaryColor
{
get
{
return favoritePrimaryColor;
}
set
{
switch (value?.ToLower())
{
case "red":
case "green":
case "blue":
favoritePrimaryColor = value;
break;
default:
throw new ArgumentException(
$"{value} is not a primary color. " +
"Choose from: red, green, blue.");
}
}
}
// indexers
public Person this[int index]
{
get
{
return Children[index]; // pass on to the List<T> indexer
}
set
{
Children[index] = value;
}
}
public Person this[string name]
{
get
{
return Children.Find(p => p.Name == name);
}
set
{
Person found = Children.Find(p => p.Name == name);
if (found is not null) found = value;
}
}
private bool married = false;
public bool Married => married;
private Person? spouse = null;
public Person? Spouse => spouse;
// static method to marry
public static void Marry(Person p1, Person p2)
{
p1.Marry(p2);
}
// instance method to marry
public void Marry(Person partner)
{
if (married) return;
spouse = partner;
married = true;
partner.Marry(this);
}
// static method to "multiply"
public static Person Procreate(Person p1, Person p2)
{
if (p1.Spouse != p2)
{
throw new ArgumentException("You must be married to procreate.");
}
Person baby = new()
{
Name = $"Baby of {p1.Name} and {p2.Name}",
DateOfBirth = DateTime.Now
};
p1.Children.Add(baby);
p2.Children.Add(baby);
return baby;
}
// instance method to "multiply"
public Person ProcreateWith(Person partner)
{
return Procreate(this, partner);
}
// operator to "marry"
public static bool operator +(Person p1, Person p2)
{
Marry(p1, p2);
return p1.Married && p2.Married; // confirm they are both now married
}
// operator to "multiply"
public static Person operator *(Person p1, Person p2)
{
return Procreate(p1, p2);
}
// method with a local function
public static int Factorial(int number)
{
if (number < 0)
{
throw new ArgumentException(
$"{nameof(number)} cannot be less than zero.");
}
return localFactorial(number);
int localFactorial(int localNumber) // local function
{
if (localNumber == 0) return 1;
return localNumber * localFactorial(localNumber - 1);
}
}
}

View file

@ -0,0 +1,7 @@
namespace Packt.Shared;
public class ImmutablePerson
{
//public string? FirstName { get; init; }
//public string? LastName { get; init; }
}

View file

@ -0,0 +1,14 @@
namespace Packt.Shared;
[Flags]
public enum WondersOfTheAncientWorld : byte
{
None = 0b_0000_0000, // i.e. 0
GreatPyramidOfGiza = 0b_0000_0001, // i.e. 1
HangingGardensOfBabylon = 0b_0000_0010, // i.e. 2
StatueOfZeusAtOlympia = 0b_0000_0100, // i.e. 4
TempleOfArtemisAtEphesus = 0b_0000_1000, // i.e. 8
MausoleumAtHalicarnassus = 0b_0001_0000, // i.e. 16
ColossusOfRhodes = 0b_0010_0000, // i.e. 32
LighthouseOfAlexandria = 0b_0100_0000 // i.e. 64
}

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PacktLibrary\PacktLibrary.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="System.Console" Static="true" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,267 @@
using Packt.Shared;
Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.GetCultureInfo("en-GB");
// Person bob = new Person(); // C# 1.0 or later
// var bob = new Person(); // C# 3.0 or later
Person bob = new(); // C# 9.0 or later
WriteLine(bob.ToString());
bob.Name = "Bob Smith";
bob.DateOfBirth = new DateTime(1965, 12, 22); // C# 1.0 or later
WriteLine(format: "{0} was born on {1:dddd, d MMMM yyyy}",
arg0: bob.Name,
arg1: bob.DateOfBirth);
Person alice = new()
{
Name = "Alice Jones",
DateOfBirth = new(1998, 3, 7) // C# 9.0 or later
};
WriteLine(format: "{0} was born on {1:dd MMM yy}",
arg0: alice.Name,
arg1: alice.DateOfBirth);
bob.FavoriteAncientWonder = WondersOfTheAncientWorld.StatueOfZeusAtOlympia;
WriteLine(
format: "{0}'s favorite wonder is {1}. Its integer is {2}.",
arg0: bob.Name,
arg1: bob.FavoriteAncientWonder,
arg2: (int)bob.FavoriteAncientWonder);
bob.BucketList =
WondersOfTheAncientWorld.HangingGardensOfBabylon
| WondersOfTheAncientWorld.MausoleumAtHalicarnassus;
// bob.BucketList = (WondersOfTheAncientWorld)18;
WriteLine($"{bob.Name}'s bucket list is {bob.BucketList}");
bob.Children.Add(new Person { Name = "Alfred" }); // C# 3.0 and later
bob.Children.Add(new() { Name = "Zoe" }); // C# 9.0 and later
WriteLine($"{bob.Name} has {bob.Children.Count} children:");
for (int childIndex = 0; childIndex < bob.Children.Count; childIndex++)
{
WriteLine($"> {bob.Children[childIndex].Name}");
}
/*
foreach (Person child in bob.Children)
{
WriteLine($"> {child.Name}");
}
*/
BankAccount.InterestRate = 0.012M; // store a shared value
BankAccount jonesAccount = new();
jonesAccount.AccountName = "Mrs. Jones";
jonesAccount.Balance = 2400;
WriteLine(format: "{0} earned {1:C} interest.",
arg0: jonesAccount.AccountName,
arg1: jonesAccount.Balance * BankAccount.InterestRate);
BankAccount gerrierAccount = new();
gerrierAccount.AccountName = "Ms. Gerrier";
gerrierAccount.Balance = 98;
WriteLine(format: "{0} earned {1:C} interest.",
arg0: gerrierAccount.AccountName,
arg1: gerrierAccount.Balance * BankAccount.InterestRate);
WriteLine($"{bob.Name} is a {Person.Species}");
WriteLine($"{bob.Name} was born on {bob.HomePlanet}");
Person blankPerson = new();
WriteLine(format:
"{0} of {1} was created at {2:hh:mm:ss} on a {2:dddd}.",
arg0: blankPerson.Name,
arg1: blankPerson.HomePlanet,
arg2: blankPerson.Instantiated);
Person gunny = new(initialName: "Gunny", homePlanet: "Mars");
WriteLine(format:
"{0} of {1} was created at {2:hh:mm:ss} on a {2:dddd}.",
arg0: gunny.Name,
arg1: gunny.HomePlanet,
arg2: gunny.Instantiated);
bob.WriteToConsole();
WriteLine(bob.GetOrigin());
(string, int) fruit = bob.GetFruit();
WriteLine($"{fruit.Item1}, {fruit.Item2} there are.");
var fruitNamed = bob.GetNamedFruit();
WriteLine($"There are {fruitNamed.Number} {fruitNamed.Name}.");
var thing1 = ("Neville", 4);
WriteLine($"{thing1.Item1} has {thing1.Item2} children.");
var thing2 = (bob.Name, bob.Children.Count);
WriteLine($"{thing2.Name} has {thing2.Count} children.");
(string fruitName, int fruitNumber) = bob.GetFruit();
WriteLine($"Deconstructed: {fruitName}, {fruitNumber}");
// Deconstructing a Person
var (name1, dob1) = bob;
WriteLine($"Deconstructed: {name1}, {dob1}");
var (name2, dob2, fav2) = bob;
WriteLine($"Deconstructed: {name2}, {dob2}, {fav2}");
WriteLine(bob.SayHello());
WriteLine(bob.SayHello("Emily"));
WriteLine(bob.OptionalParameters());
WriteLine(bob.OptionalParameters("Jump!", 98.5));
WriteLine(bob.OptionalParameters(number: 52.7, command: "Hide!"));
WriteLine(bob.OptionalParameters("Poke!", active: false));
int a = 10;
int b = 20;
int c = 30;
WriteLine($"Before: a = {a}, b = {b}, c = {c}");
bob.PassingParameters(a, ref b, out c);
WriteLine($"After: a = {a}, b = {b}, c = {c}");
int d = 10;
int e = 20;
WriteLine($"Before: d = {d}, e = {e}, f doesn't exist yet!");
// simplified C# 7.0 or later syntax for the out parameter
bob.PassingParameters(d, ref e, out int f);
WriteLine($"After: d = {d}, e = {e}, f = {f}");
Person sam = new()
{
Name = "Sam",
DateOfBirth = new(1969, 6, 25)
};
WriteLine(sam.Origin);
WriteLine(sam.Greeting);
WriteLine(sam.Age);
sam.FavoriteIceCream = "Chocolate Fudge";
WriteLine($"Sam's favorite ice-cream flavor is {sam.FavoriteIceCream}.");
sam.FavoritePrimaryColor = "Red";
WriteLine($"Sam's favorite primary color is {sam.FavoritePrimaryColor}.");
Book book = new();
book.Title = "C# 11 and .NET 7 - Modern Cross-Platform Development";
sam.Children.Add(new() { Name = "Charlie", DateOfBirth = new(2010, 3, 18) });
sam.Children.Add(new() { Name = "Ella", DateOfBirth = new(2020, 12, 24) });
// get using Children list
WriteLine($"Sam's first child is {sam.Children[0].Name}.");
WriteLine($"Sam's second child is {sam.Children[1].Name}.");
// get using integer position indexer
WriteLine($"Sam's first child is {sam[0].Name}.");
WriteLine($"Sam's second child is {sam[1].Name}.");
// get using name indexer
WriteLine($"Sam's child named Ella is {sam["Ella"].Age} years old.");
// 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.");
}
WriteLine($"{lamech.Name} is married to {lamech.Spouse?.Name ?? "nobody"}");
WriteLine($"{adah.Name} is married to {adah.Spouse?.Name ?? "nobody"}");
WriteLine($"{zillah.Name} is married to {zillah.Spouse?.Name ?? "nobody"}");
// call instance method
Person baby1 = lamech.ProcreateWith(adah);
baby1.Name = "Jabal";
WriteLine($"{baby1.Name} was born on {baby1.DateOfBirth}");
// call static method
Person baby2 = Person.Procreate(zillah, lamech);
baby2.Name = "Tubalcain";
// use operator to "multiply"
Person baby3 = lamech * adah;
baby3.Name = "Jubal";
Person baby4 = zillah * lamech;
baby4.Name = "Naamah";
WriteLine($"{lamech.Name} has {lamech.Children.Count} children.");
WriteLine($"{adah.Name} has {adah.Children.Count} children.");
WriteLine($"{zillah.Name} has {zillah.Children.Count} children.");
for (int i = 0; i < lamech.Children.Count; i++)
{
WriteLine(format: "{0}'s child #{1} is named \"{2}\".",
arg0: lamech.Name, arg1: i, arg2: lamech[i].Name);
}
// Implementing functionality using local functions
WriteLine($"5! is {Person.Factorial(5)}");
// Pattern matching with objects
object[] passengers = {
new FirstClassPassenger { AirMiles = 1_419 },
new FirstClassPassenger { AirMiles = 16_562 },
new BusinessClassPassenger(),
new CoachClassPassenger { CarryOnKG = 25.7 },
new CoachClassPassenger { CarryOnKG = 0 },
};
foreach (object passenger in passengers)
{
decimal flightCost = passenger switch
{
/* C# 8 syntax
FirstClassPassenger p when p.AirMiles > 35000 => 1500M,
FirstClassPassenger p when p.AirMiles > 15000 => 1750M,
FirstClassPassenger => 2000M, */
// C# 9 or later syntax
FirstClassPassenger p => p.AirMiles switch
{
> 35000 => 1500M,
> 15000 => 1750M,
_ => 2000M
},
BusinessClassPassenger _ => 1000M,
CoachClassPassenger p when p.CarryOnKG < 10.0 => 500M,
CoachClassPassenger _ => 650M,
_ => 800M
};
WriteLine($"Flight costs {flightCost:C} for {passenger}");
}
//ImmutablePerson jeff = new()
//{
// FirstName = "Jeff",
// LastName = "Winger"
//};
//jeff.FirstName = "Geoff";