1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

レコードのコンストラクタ引数をチェックするには

1
Posted at

Question

enum BloodType { A, B, O, AB }

record Person(
    string Name,
    int Age,
    BloodType Blood);

このPersonにおいて

  • Nameにnullが指定されたらArgumentNullException
  • Ageに0未満が指定されたらArgumentException
  • Bloodに未定義の値が指定されたらArgumentException

それぞれスローするにはどうしたらよいか。

Answer

以下のように、自動実装プロパティを同名のプロパティで上書きし、その中で自動プロパティの値にチェックをすることで実現する。

record Person(
    string Name,
    int Age,
    BloodType Blood)
{
    public string Name { get; } = Name ?? throw new ArgumentNullException();
    public int Age { get; } = 0 <= Age ? Age : throw new ArgumentException();
    public BloodType Blood { get; } = Enum.IsDefined(Blood) ? Blood : throw new ArgumentException();
}

それぞれのプロパティがgetのみ指定されているのがミソで、initまで追加してはいけない。

public string Name { get; init; } = Name ?? throw new ArgumentNullException();

こうしてしまうと、以下の2行目で例外が発生しない。

var person = new Person("俺男", 456, BloodType.A);
var person2 = person with { Name = null! };

initを指定できないので、値のチェックをおこなう場合、with式中でプロパティを指定できない。

参考にした情報

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?