Skip to main content

NullableCancellationToken

Diagnostic Rule Overview

FieldValue
IDSHIMMER1000
Analyzer titleDo not use a nullable CancellationToken
Analyzer messageCancellationToken should not be nullable
Code fix titleMake CancellationToken non-nullable
Default severityWarning
Minimum framework/language versionN/A
CategoryShimmeringUsage
Link to codeNullableCancellationTokenAnalyzer.cs
Code fix exists?Yes

Detailed Explanation

CancellationToken is a struct that follows the null object pattern, and default(CancellationToken) is CancellationToken.None, which is a valid, non-null instance representing a non-cancellable token. See also: https://devblogs.microsoft.com/premier-developer/recommended-patterns-for-cancellationtoken/

Examples

Flagged code:

using System.Threading;
using System.Threading.Tasks;

namespace Tests;
class Test
{
Task DoAsync(CancellationToken? cancellationToken = null) => Task.CompletedTask;
}

Fixed code:

using System.Threading;
using System.Threading.Tasks;

namespace Tests;
class Test
{
Task DoAsync(CancellationToken cancellationToken = default) => Task.CompletedTask;
}

Justification of the Severity

While a nullable CancellationToken (CancellationToken?) is syntactically valid, it promotes an anti-pattern that requires unnecessary null handling logic. There is no situation where you'd want to prefer Cancellation? token over CancellationToken.None.

When to Suppress

Suppress this diagnostic only if it's unmanageable to update the corresponding tests. However, you should likely be able to leverage simple string replacement (e.g. It.IsAny<CancellationToken?>() to It.IsAny<CancellationToken>() if your tests use Moq) to do this in tests as well.

Inspiration

This was inspired by Mike Cop, @madelson's internal documentation created during his time at @mastercard.