Skip to content

Instantly share code, notes, and snippets.

@wipiano
Last active October 7, 2017 15:36
Show Gist options
  • Save wipiano/78524de240b97686b2f3fdd08f8503e3 to your computer and use it in GitHub Desktop.
Save wipiano/78524de240b97686b2f3fdd08f8503e3 to your computer and use it in GitHub Desktop.
C# で かんたんな builder ref: http://qiita.com/wipiano/items/b2690d9084ea1ea6c98f
// get-only property
public string Hoge { get; }
// 下記とほぼ等価 (のはず...)
public string Hoge
{
get { return _hoge; }
}
private readonly string _hoge;
namespace BuilderSample
{
/// <summary>
/// immutable な Person class
/// </summary>
public class Person
{
public string Name { get; }
public int Age { get; }
public string MailAddress { get; }
internal Person(PersonBuilder builder)
{
this.Name = builder.Name;
this.Age = builder.Age;
this.MailAddress = builder.MailAddress;
}
}
}
using System;
namespace BuilderSample
{
/// <summary>
/// Person の builder
/// </summary>
public class PersonBuilder
{
public string Name { internal get; set; }
public int Age
{
internal get => _age.Value;
set => _age = value;
}
// 未代入チェックのために Nullable
private int? _age;
public string MailAddress { internal get; set; }
// Person オブジェクトを build
public Person Build()
{
// 未代入のプロパティをチェック
if (this.Name == null)
throw new ArgumentNullException(nameof(this.Name));
if (!_age.HasValue)
throw new ArgumentNullException(nameof(this.Age));
if (this.MailAddress == null)
throw new ArgumentNullException(nameof(this.MailAddress));
// this をそのまま渡すことでコンストラクタの引数を増やさない
return new Person(this);
}
}
}
namespace BuilderSample.Console
{
class Program
{
static void Main(string[] args)
{
// こんなふうにつかいます
Person taro = new PersonBuilder()
{
Name = "taro",
Age = 24,
MailAddress = "foo@bar.com",
}.Build();
// person からプロパティを取得できます
System.Console.WriteLine($@"{nameof(taro.Name)}: {taro.Name}
{nameof(taro.Age)}: {taro.Age}
{nameof(taro.MailAddress)}: {taro.MailAddress}
");
// こんなふうにするのはコンパイルとおりません
// taro.Age = 18; // 上書きしちゃえ!
// var hoge = new Person(new PersonBuilder()); // アセンブリの外からは Person のコンストラクタ呼べない
// 未代入のものがあると、例外
Person hanako = new PersonBuilder()
{
Name = "hanako",
// 年齢はひみつ
MailAddress = "hanako@hanahana.com"
}.Build(); // ArgumentNullException: Age
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment