はじめに
本記事はinitキーワードとrequiredキーワードを使うことでオブジェクト初期化子で生成可能なバリューオブジェクトを作る方法についてまとめます。
本記事はこちらの記事の続編です。
前回記事のサンプルの問題点
前回記事では、initキーワードを使うことでオブジェクト初期化子で生成可能なバリューオブジェクトを作る方法をまとめました。
バリューオブジェクトのクラス定義は以下のような感じです。
/// <summary>
/// バリューオブジェクト
/// </summary>
internal class ValueObject
{
#region プロパティ
/// <summary>
/// 値
/// </summary>
internal string Value { get; init; } = string.Empty;
#endregion
}
上記のバリューオブジェクトはValueプロパティがinitキーワードを使って定義されています。そのため、Valueプロパティはインスタンス生成時にオブジェクト初期化子によってのみ設定可能となり、インスタンス生成後に以下のように上書きはできません。(ビルドエラーになります。)
// 初期化以外での値の設定はできないので、以下はビルドエラーとなる
valueObject.Value = "changedValue";
ですが、前回の記事のこちらでも記載したように上記のバリューオブジェクトは、以下のように引数なしコンストラクタでインスタンス生成することができるという問題があります。
// 値の初期化をしなくてもインスタンス生成できてしまう
var valueObject = new ValueObject();
つまり、値がないバリューオブジェクトを作ることを許容してしまっています。
requiredキーワードを使って前回記事のサンプルの問題点を解消する
前章で示した問題点を解消するためC#11.0で追加されたrequiredキーワードを使います。
以下のようにバリューオブジェクトのValueプロパティにrequiredキーワードを追加することでValueプロパティの初期化が強制されます。
/// <summary>
/// バリューオブジェクト
/// </summary>
internal class ValueObject
{
#region プロパティ
/// <summary>
/// 値
/// requiredキーワードを追加し、初期化を強制する
/// </summary>
internal required string Value { get; init; } = string.Empty;
#endregion
}
初期化が強制されるので、元々できていた以下のような引数なしコンストラクタでのインスタンス生成はできなくなります。
// オブジェクト初期化子による初期化を強制しているため、以下はビルドエラーとなる
var valueObject = new ValueObject();
この書き方をすることでオブジェクト初期化子によっての初期化を強制できるようになるため、ようやくオブジェクト初期化子で生成可能なバリューオブジェクトの定義ができるようになります。
まとめ
本記事ではinitキーワードとrequiredキーワードを使うことでオブジェクト初期化子で生成可能なバリューオブジェクトを作る方法についてまとめます。
オブジェクト初期化子で生成可能なバリューオブジェクトを定義する際には、initキーワードに加えてrequiredキーワードが必要であることがわかりました。