BrotliStream no longer allows undefined CompressionLevel values

The BrotliStream constructors that take a CompressionLevel argument no longer allow values that aren't defined in the CompressionLevel enumeration. If you pass an invalid value, an ArgumentException is thrown.

Previous behavior

BrotliStream allowed you to pass an arbitrary compression level to the constructor by casting the desired level directly to CompressionLevel. For example:

BrotliStream brotli = new BrotliStream(baseStream,
                                       (CompressionLevel)5); // Use level 5

However, if an arbitrary level was provided, that was passed through as-is to the underlying library, resulting in inconsistent and potentially unexpected behavior.

New behavior

BrotliStream only allows the values defined in CompressionLevel. If you pass an undefined value to the constructor, an ArgumentException is thrown.

Version introduced

.NET 7

Type of breaking change

This change can affect binary compatibility.

Reason for change

The purpose of the CompressionLevel enumeration is to let developers use compression algorithms without needing to understand the meaning of their tuning parameters.

If an arbitrary level was provided, that was passed through as-is to the underlying library, resulting in inconsistent and potentially unexpected behavior. With this change, the behavior is aligned with other compression streams, for example, DeflateStream.

With the new tuning of the CompressionLevel values and the addition of CompressionLevel.SmallestSize, it's now possible to have a variety of trade-offs in the compression algorithms. Users can continue to rely on CompressionLevel values as being abstractions of such trade-offs.

If you were relying on passing undefined values as the CompressionLevel, revisit your use case and decide which documented value is the most optimal for it.

Affected APIs