Skip to content

Instantly share code, notes, and snippets.

@aasmundeldhuset
Last active December 21, 2015 14:19
Show Gist options
  • Select an option

  • Save aasmundeldhuset/6318964 to your computer and use it in GitHub Desktop.

Select an option

Save aasmundeldhuset/6318964 to your computer and use it in GitHub Desktop.
An approximate C# implementation of a piece of Scala code that showed how to make builders that enforce (at compile-time) that certain properties must be set.
using System;
public class Demo
{
public static void Main()
{
Person p = CreateA.Person().WithAge(23).WithName("");
Person q = CreateA.Person().WithName("").WithAge(23);
Person r = CreateA.Person().WithName("");
// The next two don't compile because the name is not set
Person s = CreateA.Person().WithAge(23);
Person t = CreateA.Person();
}
}
public class Person
{
public string Name { get; private set; }
public int Age { get; private set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
// Not necessary if you don't want any references to the builder assembly; just add .Build() at the end of each builder invocation
public static implicit operator Person(CheckedPersonBuilder<NameIsSet> builder)
{
return builder.Build();
}
}
public abstract class NameStatus
{
}
public abstract class NameIsSet : NameStatus
{
}
public abstract class NameNotSet : NameStatus
{
}
public class CheckedPersonBuilder<TNameStatus>
where TNameStatus : NameStatus
{
public String Name { get; private set; }
public int? Age { get; private set; }
public static CheckedPersonBuilder<NameNotSet> New()
{
return new CheckedPersonBuilder<NameNotSet>(null, null);
}
private CheckedPersonBuilder(string name, int? age)
{
Name = name;
Age = age;
}
public CheckedPersonBuilder<NameIsSet> WithName(string name)
{
return new CheckedPersonBuilder<NameIsSet>(name, Age);
}
public CheckedPersonBuilder<TNameStatus> WithAge(int age)
{
return new CheckedPersonBuilder<TNameStatus>(Name, age);
}
}
public static class CreateA
{
public static CheckedPersonBuilder<NameNotSet> Person()
{
return CheckedPersonBuilder<NameNotSet>.New();
}
public static Person Build(this CheckedPersonBuilder<NameIsSet> builder)
{
return new Person(builder.Name, builder.Age ?? 18);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment