'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 |