44
55using System ;
66using System . ComponentModel ;
7+ using System . Data . Common ;
78using System . Diagnostics ;
89using System . Runtime . CompilerServices ;
910using System . Runtime . InteropServices ;
@@ -55,7 +56,17 @@ public readonly ref partial struct Span2D<T>
5556 // discontiguous row, so that any arbitrary memory locations
5657 // can be used to internally represent a 2D span. This gives
5758 // users much more flexibility when creating spans from data.
58- #if NETSTANDARD2_1_OR_GREATER
59+ #if NET7_0_OR_GREATER
60+ /// <summary>
61+ /// The <typeparamref name="T"/> reference for the <see cref="Span2D{T}"/> instance.
62+ /// </summary>
63+ private readonly ref T reference ;
64+
65+ /// <summary>
66+ /// The height of the specified 2D region.
67+ /// </summary>
68+ private readonly int height ;
69+ #elif NETSTANDARD2_1_OR_GREATER
5970 /// <summary>
6071 /// The <see cref="Span{T}"/> instance pointing to the first item in the target memory area.
6172 /// </summary>
@@ -106,7 +117,12 @@ public readonly ref partial struct Span2D<T>
106117 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
107118 internal Span2D ( ref T value , int height , int width , int pitch )
108119 {
120+ #if NET7_0_OR_GREATER
121+ this . reference = ref value ;
122+ this . height = height ;
123+ #else
109124 this . span = MemoryMarshal . CreateSpan ( ref value , height ) ;
125+ #endif
110126 this . width = width ;
111127 this . Stride = width + pitch ;
112128 }
@@ -144,7 +160,10 @@ public unsafe Span2D(void* pointer, int height, int width, int pitch)
144160
145161 OverflowHelper . EnsureIsInNativeIntRange ( height , width , pitch ) ;
146162
147- #if NETSTANDARD2_1_OR_GREATER
163+ #if NET7_0_OR_GREATER
164+ this . reference = ref Unsafe . AsRef < T > ( pointer ) ;
165+ this . height = height ;
166+ #elif NETSTANDARD2_1_OR_GREATER
148167 this . span = new Span < T > ( pointer , height ) ;
149168#else
150169 this . Instance = null ;
@@ -245,7 +264,10 @@ public Span2D(T[] array, int offset, int height, int width, int pitch)
245264 ThrowHelper . ThrowArgumentException ( ) ;
246265 }
247266
248- #if NETSTANDARD2_1_OR_GREATER
267+ #if NET7_0_OR_GREATER
268+ this . reference = ref array . DangerousGetReferenceAt ( offset ) ;
269+ this . height = height ;
270+ #elif NETSTANDARD2_1_OR_GREATER
249271 this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReferenceAt ( offset ) , height ) ;
250272#else
251273 this . Instance = array ;
@@ -277,7 +299,10 @@ public Span2D(T[,]? array)
277299 ThrowHelper . ThrowArrayTypeMismatchException ( ) ;
278300 }
279301
280- #if NETSTANDARD2_1_OR_GREATER
302+ #if NET7_0_OR_GREATER
303+ this . reference = ref array . DangerousGetReference ( ) ;
304+ this . height = array . GetLength ( 0 ) ;
305+ #elif NETSTANDARD2_1_OR_GREATER
281306 this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReference ( ) , array . GetLength ( 0 ) ) ;
282307#else
283308 this . Instance = array ;
@@ -344,7 +369,10 @@ public Span2D(T[,]? array, int row, int column, int height, int width)
344369 ThrowHelper . ThrowArgumentOutOfRangeExceptionForWidth ( ) ;
345370 }
346371
347- #if NETSTANDARD2_1_OR_GREATER
372+ #if NET7_0_OR_GREATER
373+ this . reference = ref array . DangerousGetReferenceAt ( row , column ) ;
374+ this . height = height ;
375+ #elif NETSTANDARD2_1_OR_GREATER
348376 this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReferenceAt ( row , column ) , height ) ;
349377#else
350378 this . Instance = array ;
@@ -376,7 +404,10 @@ public Span2D(T[,,] array, int depth)
376404 ThrowHelper . ThrowArgumentOutOfRangeExceptionForDepth ( ) ;
377405 }
378406
379- #if NETSTANDARD2_1_OR_GREATER
407+ #if NET7_0_OR_GREATER
408+ this . reference = ref array . DangerousGetReferenceAt ( depth , 0 , 0 ) ;
409+ this . height = array . GetLength ( 1 ) ;
410+ #elif NETSTANDARD2_1_OR_GREATER
380411 this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReferenceAt ( depth , 0 , 0 ) , array . GetLength ( 1 ) ) ;
381412#else
382413 this . Instance = array ;
@@ -434,7 +465,10 @@ public Span2D(T[,,] array, int depth, int row, int column, int height, int width
434465 ThrowHelper . ThrowArgumentOutOfRangeExceptionForWidth ( ) ;
435466 }
436467
437- #if NETSTANDARD2_1_OR_GREATER
468+ #if NET7_0_OR_GREATER
469+ this . reference = ref array . DangerousGetReferenceAt ( depth , row , column ) ;
470+ this . height = height ;
471+ #elif NETSTANDARD2_1_OR_GREATER
438472 this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReferenceAt ( depth , row , column ) , height ) ;
439473#else
440474 this . Instance = array ;
@@ -512,7 +546,12 @@ internal Span2D(Span<T> span, int offset, int height, int width, int pitch)
512546 ThrowHelper . ThrowArgumentException ( ) ;
513547 }
514548
549+ #if NET7_0_OR_GREATER
550+ this . reference = ref span . DangerousGetReferenceAt ( offset ) ;
551+ this . height = height ;
552+ #else
515553 this . span = MemoryMarshal . CreateSpan ( ref span . DangerousGetReferenceAt ( offset ) , height ) ;
554+ #endif
516555 this . width = width ;
517556 this . Stride = width + pitch ;
518557 }
@@ -580,7 +619,9 @@ public int Height
580619 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
581620 get
582621 {
583- #if NETSTANDARD2_1_OR_GREATER
622+ #if NET7_0_OR_GREATER
623+ return this. height;
624+ #elif NETSTANDARD2_1_OR_GREATER
584625 return this. span. Length;
585626#else
586627 return this. height;
@@ -902,7 +943,9 @@ public unsafe ref T GetPinnableReference()
902943
903944 if ( Length ! = 0 )
904945 {
905- #if NETSTANDARD2_1_OR_GREATER
946+ #if NET7_0_OR_GREATER
947+ r0 = ref this . reference ;
948+ #elif NETSTANDARD2_1_OR_GREATER
906949 r0 = ref MemoryMarshal . GetReference ( this . span ) ;
907950#else
908951 r0 = ref RuntimeHelpers . GetObjectDataAtOffsetOrPointerReference < T > ( this . Instance , this . Offset ) ;
@@ -919,7 +962,9 @@ public unsafe ref T GetPinnableReference()
919962 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
920963 public ref T DangerousGetReference( )
921964 {
922- #if NETSTANDARD2_1_OR_GREATER
965+ #if NET7_0_OR_GREATER
966+ return ref this . reference;
967+ #elif NETSTANDARD2_1_OR_GREATER
923968 return ref MemoryMarshal . GetReference ( this . span ) ;
924969#else
925970 return ref RuntimeHelpers . GetObjectDataAtOffsetOrPointerReference < T > ( this . Instance , this . Offset ) ;
@@ -935,7 +980,9 @@ public ref T DangerousGetReference()
935980 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
936981 public ref T DangerousGetReferenceAt( int i , int j )
937982 {
938- #if NETSTANDARD2_1_OR_GREATER
983+ #if NET7_0_OR_GREATER
984+ ref T r0 = ref this . reference ;
985+ #elif NETSTANDARD2_1_OR_GREATER
939986 ref T r0 = ref MemoryMarshal . GetReference ( this . span ) ;
940987#else
941988 ref T r0 = ref RuntimeHelpers . GetObjectDataAtOffsetOrPointerReference < T > ( this . Instance , this . Offset ) ;
@@ -982,7 +1029,11 @@ public unsafe Span2D<T> Slice(int row, int column, int height, int width)
9821029 nint shift = ( ( nint ) ( uint ) this . Stride * ( nint ) ( uint ) row) + ( nint ) ( uint ) column;
9831030 int pitch = this . Stride - width;
9841031
985- #if NETSTANDARD2_1_OR_GREATER
1032+ #if NET7_0_OR_GREATER
1033+ ref T r0 = ref Unsafe. Add( ref this . reference, shift) ;
1034+
1035+ return new ( ref r0, height, width, pitch) ;
1036+ #elif NETSTANDARD2_1_OR_GREATER
9861037 ref T r0 = ref this . span. DangerousGetReferenceAt( shift) ;
9871038
9881039 return new ( ref r0, height, width, pitch) ;
@@ -1024,7 +1075,11 @@ public bool TryGetSpan(out Span<T> span)
10241075 if ( this . Stride == this . width &&
10251076 Length <= int . MaxValue)
10261077 {
1027- #if NETSTANDARD2_1_OR_GREATER
1078+ #if NET7_0_OR_GREATER
1079+ span = MemoryMarshal. CreateSpan( ref this . reference, ( int ) Length) ;
1080+
1081+ return true;
1082+ #elif NETSTANDARD2_1_OR_GREATER
10281083 span = MemoryMarshal. CreateSpan( ref MemoryMarshal. GetReference( this . span) , ( int ) Length) ;
10291084
10301085 return true;
@@ -1135,7 +1190,10 @@ public override string ToString()
11351190 public static bool operator == ( Span2D < T > left , Span2D < T > right )
11361191 {
11371192 return
1138- #if NETSTANDARD2_1_OR_GREATER
1193+ #if NET7_0_OR_GREATER
1194+ Unsafe . AreSame ( ref left . reference , ref right . reference ) &&
1195+ left . height == right . height &&
1196+ #elif NETSTANDARD2_1_OR_GREATER
11391197 left . span = = right . span &&
11401198#else
11411199 ReferenceEquals (
0 commit comments