Edit

Share via


Span2D<T>.Slice(Int32, Int32, Int32, Int32) Method

Definition

Slices the current instance with the specified parameters.

public CommunityToolkit.HighPerformance.Span2D<T> Slice(int row, int column, int height, int width);
member this.Slice : int * int * int * int -> CommunityToolkit.HighPerformance.Span2D<'T>
Public Function Slice (row As Integer, column As Integer, height As Integer, width As Integer) As Span2D(Of T)

Parameters

row
Int32

The target row to map within the current instance.

column
Int32

The target column to map within the current instance.

height
Int32

The height to map within the current instance.

width
Int32

The width to map within the current instance.

Returns

A new Span2D<T> instance representing a slice of the current one.

Exceptions

Thrown when either height, width or height are negative or not within the bounds that are valid for the current instance.

Thrown when either height, width or height are negative or not within the bounds that are valid for the current instance.

Remarks

Contrary to Slice(Int32, Int32), this method will throw an ArgumentOutOfRangeException if attempting to perform a slice operation that would result in either axes being 0. That is, trying to call Slice(Int32, Int32, Int32, Int32) as eg. Slice(row: 1, column: 0, height: 0, width: 2) on an instance that has 1 row and 2 columns will throw, rather than returning a new Span2D<T> instance with 0 rows and 2 columns. For contrast, trying to eg. call Slice(start: 1, length: 0) on a Span<T> instance of length 1 would return a span of length 0, with the internal reference being set to right past the end of the memory.

This is by design, and it is due to the internal memory layout that Span2D<T> has. That is, in the case of Span<T>, the only edge case scenario would be to obtain a new span of size 0, referencing the very end of the backing object (eg. an array or a String instance). In that case, the GC can correctly track things. With Span2D<T>, on the other hand, it would be possible to slice an instance with a sizeof 0 in either axis, but with the computed starting reference pointing well past the end of the internal memory area. Such a behavior would not be valid if the reference was pointing to a managed object, and it would cause memory corruptions (ie. "GC holes").

If you specifically need to be able to obtain empty values from slicing past the valid range, consider performing the range validation yourself (ie. through some helper method), and then only invoking Slice(Int32, Int32, Int32, Int32) once the parameters are in the accepted range. Otherwise, consider returning another return explicitly, such as Empty.

Applies to