Skip to content

Instantly share code, notes, and snippets.

@amis92
Forked from HaloFour/Test.cs
Created March 18, 2020 10:44
Show Gist options
  • Save amis92/dfc52fb774d44194f8846b2f560c2f96 to your computer and use it in GitHub Desktop.
Save amis92/dfc52fb774d44194f8846b2f560c2f96 to your computer and use it in GitHub Desktop.
Test inheritance with struct builders
/*
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