BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース C#でImmutable Object Graphsを簡単に作る

C#でImmutable Object Graphsを簡単に作る

ブックマーク

原文(投稿日:2013/05/10)へのリンク

C#で単純な不変(immutable)クラスを作るのは簡単である。コンストラクタを作成し、publicセッターの作成に失敗するようにするだけである。しかしこれだけでは不十分なこともある。最終的には、効率のためにディープグラフを作成したいことがあるためビルダーで作成するべきである。もしくは(DateTimeのAddMinutesメソッドのように)フィールドが変更されて、オブジェクトのコピーを返す作成メソッドにより破棄できない更新を作成したくなるかもしれない。これらのビルダーとメソッドを作ることは非常に退屈なため、エラーが発生しやすくなる。

Andrew L Arnott氏は、T4ベースのコードジェネレーターに依存するソリューションを提供する。T4になじみがないのであれば、Text Template Transformation Toolkitの略称である。これはVisual Studioのコード生成機能とライブラリで、Entity Frameworkはこれに依存している。このT4スクリプトは、可変クラスを受け取ると不変クローンを生成する。

Andrew氏のツールキットは、publicコンストラクタを発行しないようにするためにやや物議を醸す決定が行われている。代わりに静的なCreateメソッドを使うか、Defaultインスタンスではじめて、それから変更することが期待されている。これはWithXxxメソッドを使用して、プロパティごとに存在するようにする。

私たちは2つの拡張方法を考えています。多くのプロパティを持つクラスで、一度にいくつかのプロパティを変更する必要がある場合、各プロパティの変更ごとに新しいオブジェクトを割り当てるのは無駄であり、GCの圧迫に貢献することになります。そのため私はクラスのすべてのプロパティにオプショナルパラメータを取るWithメソッドを追加して、バルクでプロパティを変更できるようにしました。最後にオブジェクトを作成していくつかの変更をしたいけど、複数のステップを踏みたくない(または単純にプロパティセッターにWith-メソッドを呼び出したい)というシナリオでは、私たちはBuilderクラスを作って、設定が完了したら普遍のコピーを返してくれます。このパターンは、.NET FrameworkのStringとStringBuilderによく似ていて、また先に述べた最近の不変コレクションにも似ています。

もちろんそれが気に入らなかった時には簡単にT4テンプレートを変更することができる。Andrew氏は、それを容易にするために、意図的にテンプレートを小さなファイルに分解している。また、ベーステンプレートを変更しなくても拡張することもできる。

コードジェネレーターですべて書かれたものと同じく、これはpartialメソッドをヘビーに使用している。partialメソッドは生成されたファイルを変更することなく、コード生成されたメソッドにロジックを注入することができる。例えばひとつは不変オブジェクトにpartialのデフォルト値をセットするメソッドを実装することができる。実装されていないpartialメソッドはコンパイラによって自動的に削除されるため、実行時コストがかからない。

Arron氏の実験は、Immutable Object Graphsという彼のブログで詳細を読むことができる。

この記事に星をつける

おすすめ度
スタイル

BT