'Fluence Builder Inheritance with Recursive Generics

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Creational.Builder
{
    public class Person
    {
        public string Name;

        public string Position;

        public class Builder : PersonInfoBuilder<Builder>
        {

        }

        public static Builder New => new Builder();

        public override string ToString()
        {
            return $"{nameof(Name)}: {Name}, {nameof(Position)}: {Position}";
        }
    }

    public abstract class PersonBuilder
    {
        protected Person person = new Person();

        public Person Build()
        {
            return person;
        }
    }

    // class Foo : Bar<Foo>
    public class PersonInfoBuilder<SELF> : PersonBuilder
      where SELF : PersonInfoBuilder<SELF>
    {
        public SELF Called(string name)
        {
            person.Name = name;
            return (SELF)this;
        }
    }

    public class PersonJobBuilder<SELF> : PersonInfoBuilder<PersonJobBuilder<SELF>>
      where SELF : PersonJobBuilder<SELF>
    {
        public SELF WorksAsA(string position)
        {
            person.Position = position;
            return (SELF)this;
        }
    }

    internal class Program
    {
        public static void Main(string[] args)
        {
            var me = Person.New
                .Called("Harry")
                .WorksAsA("Testing")
                .Build();
            Console.WriteLine(me);

            var builder = new Builder();
            var person = builder.WorksAsA("d").
            Console.WriteLine(person);
        }
    }
}

The code from a course Designpatterns, but it will not perfect. I get the following errors:

Person.Builder' does not contain a definition for 'WorksAsA' and no extension method 'WorksAsA' accepting a first argument of type 'Person.Builder' could be found (are you missing a using directive or an assembly reference?)

Builder' is a namespace but is used like a type Creational.Builder

Cannot use local variable 'person' before it is declared

How can I fixed these problems??



Solution 1:[1]

WorksAsa is a method in PersonJobBuilder and the inheritance hierarchy of classes are:

PersonBuilder <- PersonInfoBuilder <-PersonJobBuilder

so, call the last class PersonJobBuilder.

In Person class: modify this line

  public class Builder : PersonInfoBuilder<Builder>    
        {

        }

to

        public class Builder : PersonJobBuilder<Builder>
        {

        }

A working example Tryit online

output:

Name: Harry, Position: Testing
Creational.Builder2.Person+Builder

You can simplify your inheritance as you use recursive generic type

public class PersonJobBuilder<SELF> : PersonInfoBuilder<SELF>
      where SELF : PersonJobBuilder<SELF>

Solution 2:[2]

public class Builder : PersonInfoBuilder<Builder>
{

}

must be:

public class Builder : PersonJobBuilder<Builder>
{

}

And WorksAsa is solved but NOT the other issues.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 M.Hassan
Solution 2 Liam