Наследование PersonBuilder
- просто шум, ваш вопрос об этом шаблоне:
class PersonInfoBuilder<SELF> where SELF : PersonInfoBuilder<SELF>
Давайте изменим имена и создадим запутанный пример, который использует шаблон:
abstract class CompatibleAnimal<T> where T: CompatibleAnimal<T>
{
public abstract CompatibleAnimal<T> BreedWith(T t);
}
abstract class Equine: CompatibleAnimal<Equine>
{
public override abstract CompatibleAnimal<Equine> BreedWith(Equine t);
}
class Mule: Equine {
public override CompatibleAnimal<Equine> BreedWith(Equine t)
{
return null;
}
public override string ToString() => "mules";
}
class Horse: Equine {
public override CompatibleAnimal<Equine> BreedWith(Equine t)
{
if (t is Donkey)
return new Mule();
if (t is Horse)
return new Horse();
return null;
}
public override string ToString() => "horses";
}
class Donkey: Equine
{
public override CompatibleAnimal<Equine> BreedWith(Equine t)
{
if (t is Donkey)
return new Donkey();
if (t is Horse)
return new Mule();
return null;
}
public override string ToString() => "donkeys";
}
А теперь:
public static void Main() {
Console.WriteLine(
$@"If you cross horses with horses you get {
new Horse().BreedWith(new Horse())?.ToString() ?? "nothing"}");
Console.WriteLine(
$@"If you cross donkeys with donkeys you get {
new Donkey().BreedWith(new Donkey())?.ToString() ?? "nothing"}");
Console.WriteLine(
$@"If you cross horses with donkeys you get {
new Horse().BreedWith(new Donkey())?.ToString() ?? "nothing"}");
Console.WriteLine(
$@"If you cross mules with mules you get {
new Mule().BreedWith(new Mule())?.ToString() ?? "nothing"}");
Console.WriteLine(
$@"If you cross mules with donkeys you get {
new Mule().BreedWith(new Donkey())?.ToString() ?? "nothing"}");
Console.WriteLine(
$@"If you cross mules with horses you get {
new Mule().BreedWith(new Horse())?.ToString() ?? "nothing"}");
}
И, конечно, если вы создадите подобную иерархию классов для собак, система типов не позволит вам случайно развести лошадей с собакой, которая выглядит как хорошая идея.