-
-
Save amis92/dfc52fb774d44194f8846b2f560c2f96 to your computer and use it in GitHub Desktop.
Test inheritance with struct builders
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
public record class Person { | |
public required int ID { get; init; } | |
public string FirstName { get; init; } | |
public string LastName { get; init; } | |
} | |
public record class Student : Person { | |
public required double Gpa { get; init; } | |
} | |
*/ | |
using System; | |
public class Person { | |
public int ID { get; } | |
public string FirstName { get; } | |
public string LastName { get; } | |
public Person(Builder builder) : this(null, builder) { } | |
protected Person(Person prototype, Builder builder) { | |
if (prototype != null) { | |
ID = builder.IDSet ? builder.ID : prototype.ID; | |
FirstName = builder.FirstNameSet ? builder.FirstName : prototype.FirstName; | |
LastName = builder.LastNameSet ? builder.LastName : prototype.LastName; | |
} | |
else { | |
if (!builder.IDSet) throw new InvalidOperationException(); | |
ID = builder.ID; | |
FirstName = builder.FirstName; | |
LastName = builder.LastName; | |
} | |
} | |
public static Builder NewBuilder() => default; | |
public virtual Person With(Builder builder) { | |
return new Person(this, builder); | |
} | |
public struct Builder { | |
private byte _set; | |
private int _id; | |
private string _firstName; | |
private string _lastName; | |
public int ID { | |
get => _id; | |
set { | |
_id = value; | |
_set |= 1; | |
} | |
} | |
public string FirstName { | |
get => _firstName; | |
set { | |
_firstName = value; | |
_set |= 2; | |
} | |
} | |
public string LastName { | |
get => _lastName; | |
set { | |
_lastName = value; | |
_set |= 4; | |
} | |
} | |
public bool IDSet => (_set & 1) == 1; | |
public bool FirstNameSet => (_set & 2) == 2; | |
public bool LastNameSet => (_set & 4) == 4; | |
} | |
} | |
public class Student : Person { | |
public double Gpa { get; } | |
public Student(Builder builder) : this(null, builder) { } | |
protected Student(Student prototype, Builder builder) : base(prototype, builder.Parent) { | |
if (prototype != null) { | |
Gpa = builder.GpaSet ? builder.Gpa : prototype.Gpa; | |
} | |
else { | |
if (!builder.GpaSet) throw new InvalidOperationException(); | |
Gpa = builder.Gpa; | |
} | |
} | |
public override Person With(Person.Builder builder) { | |
return new Student(this, new Builder() { Parent = builder }); | |
} | |
public virtual Student With(Student.Builder builder) { | |
return new Student(this, builder); | |
} | |
public new struct Builder { | |
private Person.Builder _parentBuilder; | |
private byte _set; | |
private double _gpa; | |
public Person.Builder Parent { | |
get => _parentBuilder; | |
set => _parentBuilder = value; | |
} | |
public int ID { | |
get => _parentBuilder.ID; | |
set { | |
var temp = _parentBuilder; | |
temp.ID = value; | |
_parentBuilder = temp; | |
} | |
} | |
public string FirstName { | |
get => _parentBuilder.FirstName; | |
set { | |
var temp = _parentBuilder; | |
temp.FirstName = value; | |
_parentBuilder = temp; | |
} | |
} | |
public string LastName { | |
get => _parentBuilder.LastName; | |
set { | |
var temp = _parentBuilder; | |
temp.LastName = value; | |
_parentBuilder = temp; | |
} | |
} | |
public double Gpa { | |
get => _gpa; | |
set { | |
_gpa = value; | |
_set |= 1; | |
} | |
} | |
public bool IDSet => _parentBuilder.IDSet; | |
public bool FirstNameSet => _parentBuilder.FirstNameSet; | |
public bool LastNameSet => _parentBuilder.LastNameSet; | |
public bool GpaSet => (_set & 1) == 1; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment