【Unity】.NET CommunityToolkit Diagnosticsでガード句を書く

Unityで.NET CommunityToolkit Diagnosticsでガード句を書く方法です。

Unity 6000.3.6f1
CommunityToolkit.Diagnostics 8.4.2

.NET CommunityToolkit Diagnosticsとは?

.NET CommunityToolkit Diagnostics は、ガード句を効率的に記述するための Guard クラスを主に含む、Microsoft のパッケージです。

ガードというと早期リターンを想像する人も多いのかもしれませんが、そうではなく引数や状態のバリデーションを、例外スローまで含めて 1 行で書くためのヘルパーです。

「契約による設計」における前提条件の検証ツールと言ってもいいかもしれません。これを使うと以下のように前提条件を書くことができます。

using CommunityToolkit.Diagnostics;

public sealed class Example
{
    public void Process(string input)
    {
        // input が null の場合、ArgumentNullException をスロー
        Guard.IsNotNull(input);

        // 処理...
    }
}

本記事では、Unityにおけるこれの使い方についてまとめます。

使い方

まずインストールは NuGet から行います。今回は NuGet for Unity を使います。詳細は省略します。

NuGet For Unity

主要な書き方は以下の通りです。

using System.Collections.Generic;
using CommunityToolkit.Diagnostics;

public sealed class Example
{
    public void Process(
        string text,
        int value,
        double percentage,
        int[] numbers,
        object obj)
    {
        // 引数が null でないか
        Guard.IsNotNull(text);
        // 文字列が null または空 ("") でないか
        Guard.IsNotNullOrEmpty(text);
        // 文字列が null, 空, または空白文字のみでないか
        Guard.IsNotNullOrWhiteSpace(text);

        // 指定した値と等しいか / 等しくないか
        Guard.IsEqualTo(value, 100);
        Guard.IsNotEqualTo(value, 0);
        // 値が 0 より大きいか(正数か)
        Guard.IsGreaterThan(value, 0);
        // 値が 100 以下か
        Guard.IsLessThanOrEqualTo(value, 100);
        // 範囲内(0.0 ~ 1.0)にあるか(境界値を含む)
        Guard.IsInRange(percentage, 0.0, 1.0);
        // 範囲外にあるか
        Guard.IsNotInRange(value, 500, 1000);

        // コレクションが null でないか
        Guard.IsNotNull(numbers);
        // コレクションに要素が含まれているか
        Guard.IsNotEmpty(numbers);
        // 要素数がちょうど 3 か
        Guard.HasSizeEqualTo(numbers, 3);
        // 要素数が 10 以下か
        Guard.HasSizeLessThanOrEqualTo(numbers, 10);

        // 特定の型であることを確認
        Guard.IsOfType<string>(obj);
        // 特定の型に代入可能かを確認
        Guard.IsAssignableToType<IEnumerable<int>>(numbers);
        // 参照が同一であるか
        Guard.IsReferenceEqualTo(obj, obj);
        // 参照が別物であるか
        Guard.IsReferenceNotEqualTo(obj, new object());

        // 条件が真であるか (特定のプロパティ検査などに便利)
        Guard.IsTrue(value % 2 == 0, nameof(value), "値は偶数である必要があります。");
        // 条件が偽であるか
        Guard.IsFalse(text.Length > 1000);
    }
}

参考

learn.microsoft.com