一般的な善の降順でいくつかの解決策を次に示します。
1. default(CancellationToken)
デフォルト値として使用:
Task DoAsync(CancellationToken ct = default(CancellationToken)) { … }
意味的にCancellationToken.None
は、デフォルトの理想的な候補になりますが、コンパイル時の定数ではないため、そのままでは使用できません。default(CancellationToken)
これはコンパイル時の定数であり、公式にと同等であると文書化されているCancellationToken.None
ため、次善の策です。
2. CancellationToken
パラメータなしでメソッドオーバーロードを提供する:
または、オプションのパラメーターよりもメソッドのオーバーロードを好む場合(このトピックに関するこの質問とこの質問を参照):
Task DoAsync(CancellationToken ct) { … } // actual method always requires a token
Task DoAsync() => DoAsync(CancellationToken.None); // overload producing a default token
インターフェースメソッドの場合、拡張メソッドを使用して同じことが実現できます。
interface IFoo
{
Task DoAsync(CancellationToken ct);
}
static class Foo
{
public static Task DoAsync(this IFoo foo) => foo.DoAsync(CancellationToken.None);
}
その結果、インターフェースがスリムになり、実装者が転送メソッドのオーバーロードを明示的に記述する必要がなくなります。
3.パラメータをヌル可能にしnull
、デフォルト値として使用します。
Task DoAsync(…, CancellationToken? ct = null)
{
… ct ?? CancellationToken.None …
}
null可能な型には実行時のオーバーヘッドがわずかにあり、キャンセルトークンへの参照がnullの合体演算子のために冗長になるため、私はこのソリューションが最も好きではありません??
。
CancellationToken.None
それ以上のものになった場合、コードで何が起こるか考えてくださいdefault(CancellationToken)
。