Edit

Share via


CA1844: Provide memory-based overrides of async methods when subclassing 'Stream'

Property Value
Rule ID CA1844
Title Provide memory-based overrides of async methods when subclassing 'Stream'
Category Performance
Fix is breaking or non-breaking Non-breaking
Enabled by default in .NET 8 As suggestion

Cause

A type derived from Stream overrides ReadAsync(Byte[], Int32, Int32, CancellationToken) but does not override ReadAsync(Memory<Byte>, CancellationToken). Or, a type derived from Stream overrides WriteAsync(Byte[], Int32, Int32, CancellationToken) but does not override WriteAsync(ReadOnlyMemory<Byte>, CancellationToken).

Rule description

The memory-based ReadAsync and WriteAsync methods were added to improve performance, which they accomplish in multiple ways:

  • They return ValueTask and ValueTask<int> instead of Task and Task<int>, respectively.
  • They allow any type of buffer to be passed in without having to perform an extra copy to an array.

In order to realize these performance benefits, types that derive from Stream must provide their own memory-based implementation. Otherwise, the default implementation will be forced to copy the memory into an array in order to call the array-based implementation, resulting in reduced performance. When the caller passes in a Memory<T> or ReadOnlyMemory<T> instance that's not backed by an array, performance is affected more.

How to fix violations

The easiest way to fix violations is to rewrite your array-based implementation as a memory-based implementation, and then implement the array-based methods in terms of the memory-based methods.

When to suppress warnings

It's safe to suppress a warning from this rule if any of the following situations apply:

  • The performance hit is not a concern.
  • You know that your Stream subclass will only ever use the array-based methods.
  • Your Stream subclass has dependencies that don't support memory-based buffers.

Suppress a warning

If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.

#pragma warning disable CA1844
// The code that's violating the rule is on this line.
#pragma warning restore CA1844

To disable the rule for a file, folder, or project, set its severity to none in the configuration file.

[*.{cs,vb}]
dotnet_diagnostic.CA1844.severity = none

For more information, see How to suppress code analysis warnings.

See also