Effective JavaのアレをC#で

ねた元はこちら:
なんぞこれ。コンストラクタパラメータが異常に大杉る・・・。バカなの?死ぬの?そういう場合はBuilderパターンを検討してみよう。 - Bug Catharsis
C#3.0とC#4.0の2つを考えてみました。


まず、ネタ元の本文に

このEffective JavaでJoshua Bloch氏が提案しているBuilderパターンは、
Pythonに見られる名前付きオプションパラメータを模倣してJavaで実装したたもので、

http://d.hatena.ne.jp/zecl/20091117/p1

「実装したもので、」という部分がJavaソースコードの冗長さをも表現しているのだと信じて止みませんが、脱線しましたが、話を戻しますが、えーっと、ということですので、1つめはC#4.0で加わったオプショナル引数をそのまま使っています。*1
2つめは、オプショナル引数が加わる前の、C#3.0での場合を考えてみました。コンストラクタ呼び出し時にプロパティを初期化できる、という点を利用しました。
以下がソースになります。何でもかんでも長いJavaよりは多少スッキリしたのではないでしょうか。

class Program
{
    static void Main( string[] args )
    {
        // C# 4.0
        var foo = new VeryNiceClass( 10, 20, optional2 : 30 );
        Console.WriteLine( foo );

        // C# 3.0
        var bar = new HyperUltraClass.Builder( 256, 512 )
                    { Optional1 = 1024, Optional3 = 2048 }.Build();
        Console.WriteLine( bar );
    }
}


// C# 4.0 ~
public class VeryNiceClass
{
    private readonly int necessary1, necessary2;
    private readonly int? optional1, optional2, optional3;
    public VeryNiceClass( int necessary1, int necessary2,
                            int? optional1 = null, int? optional2 = null, int? optional3 = null )
    {
        this.necessary1 = necessary1;
        this.necessary2 = necessary2;
        this.optional1 = optional1;
        this.optional2 = optional2;
        this.optional3 = optional3;
    }

    public override string ToString()
    {
        return this.necessary1 + ":" + this.necessary2 + ":"
            + (this.optional1??0) + ":" + (this.optional2??0) + ":" + (this.optional3??0);
    }
}


// C# 3.0 ~
public class HyperUltraClass
{
    private readonly int necessary1, necessary2;
    private readonly int? optional1, optional2, optional3;
    public class Builder
    {
        private int necessary1, necessary2;
        public int? Optional1 { get; set; }
        public int? Optional2 { get; set; }
        public int? Optional3 { get; set; }
        public Builder( int necessary1, int necessary2 )
        {
            this.necessary1 = necessary1;
            this.necessary2 = necessary2;
        }

        public HyperUltraClass Build()
        {
            return new HyperUltraClass( necessary1, necessary2,
                                        this.Optional1, this.Optional2, this.Optional3 );
        }
    }

    private HyperUltraClass( int necessary1, int necessary2,
                                int? optional1, int? optional2, int? optional3 )
    {
        this.necessary1 = necessary1;
        this.necessary2 = necessary2;
        this.optional1 = optional1;
        this.optional2 = optional2;
        this.optional3 = optional3;
    }

    public override string ToString()
    {
        return this.necessary1 + ":" + this.necessary2 + ":"
            + (this.optional1??0) + ":" + (this.optional2??0) + ":" + (this.optional3??0);
    }
}

すごい久しぶりにC#触りました・・・。
やっぱりF#に比べてインテリセンスきもちい・・・。

*1:あまり人気がないような気がするオプショナル引数ですが、僕は結構好きです。(大量のオーバーロードを定義せずに済んだりetc)