提供任意內存的連續區域的類型安全且內存安全的只讀(ReadOnly)表示形式。
[ System . Runtime . InteropServices . Marshalling . NativeMarshalling ( typeof ( System . Runtime . InteropServices . Marshalling . ReadOnlySpanMarshaller < , > ) ) ]
public readonly ref struct ReadOnlySpan<T>
類型參數
| 參數 | 註解 |
|---|---|
| T | ReadOnlySpan 中項的類型 |
繼承
| Object | ValueType | ReadOnlySpan < T > |
|---|
特性
NativeMarshallingAttribute
註解
ReadOnlySpan < T > 類型是一種 ref struct,它在棧上分配,而非託管堆上。ref struct 類型有諸多限制,以確保它們不會被提升到託管堆,其中包括:它們不能被裝箱,不能賦值給 Object 類型、dynamic 類型的變量或任何接口類型的變量,不能作為引用類型中的字段,也不能跨 await 和 yield 邊界使用。此外,調用 Equals ( Object ) 和 GetHashCode 這兩個方法會拋出 NotSupportedException。
ReadOnlySpan < T > 實例通常用於存儲數組的元素或數組的一部分。不過,與數組不同的是,ReadOnlySpan < T > 實例可以指向託管內存、本機內存或堆棧上管理的內存。
構造函數
重載
| 重載 | 註解 |
|---|---|
| ReadOnlySpan < T > ( T ) | 圍繞指定的引用創建一個長度為 1 的新 ReadOnlySpan < T > |
| ReadOnlySpan < T > ( T [ ] ) | 在指定數組的整個範圍內創建一個新 ReadOnlySpan < T > |
| ReadOnlySpan < T > ( T [ ] , Int32 索引 , Int32 元素數 ) | 在指定數組的整個範圍內創建一個新 ReadOnlySpan < T > |
| Span < T > ( void* 指針 , Int32 元素數 ) | 從指定的內存地址開始,從指定數量的 T 元素創建一個新的Span < T > 對象 |
public ReadOnlySpan ( ref readonly T 引用 );
public ReadOnlySpan ( T [ ]? 數組 );
public Span ( T [ ]? 數組 , int 起始索引 , int 元素數 );
[ System . CLSCompliant ( false ) ]
public Span ( void* 指針 , int 長度 );
參數
| 參數 | 類型 | 註解 |
|---|---|---|
| 引用 | T | 任意類型的單個值(傳遞的是對其的引用),單個值的 ReadonlySpan |
| 數組 | T [ ]? | 任意類型的數組,對其元素引用的 Span |
| 起始索引
元素數 |
int | 當 Span 的元素只是引用 數組 中的一部分時,指定起始索引和元素數(省略元素數將引用 起始索引 後的所有元素) |
| 指針 | void* | 指向內存中指定數量的 T 元素起始地址的指針 |
| 長度 | int | 要包含在 Span < T > 中的 T 元素數量 |
異常
| 異常 | 註解 |
|---|---|
| ArrayTypeMismatchException | T 是引用類型,但 數組 不是 T 類型的數組 |
| ArgumentException | 若指定 指針 和 長度,T 是引用類型或包含指針,因此無法存儲在非託管內存中 |
| ArgumentOutOfRangeException | 若指定 指針 和 長度,但長度小於 0
若指定 起始索引 和 元素數,起始索引 + 元素數 > 數組 . Length 或 起始索引 > 數組 . Length 或 數組 為 null,但 起始索引 和/或 元素數 不是 0 |
示例
以下示例演示了 ReadOnlySpan 構造函數的基礎示例:
int ZHS = 1;
ReadOnlySpan < int > ZHSSpan = new ( ref ZHS );
foreach ( var z in ZHSSpan )
Console . WriteLine ( z );
int [ ] ZHSs = [ 2 , 3 , 4 ];
ReadOnlySpan < int > ZHSsSpan = new ( ZHSs );
foreach ( var z in ZHSsSpan )
Console . WriteLine ( z );
ReadOnlySpan < int > ZHSsBFSpan = new ( ZHSs , 1 , 2 );
foreach ( var z in ZHSsBFSpan )
Console . WriteLine ( z );
屬性
Empty 和 IsEmpty
Empty 返回一個空的(不是 null)ReadOnlySpan < T > 對象;IsEmpty 返回指定 ReadOnlySpan 對象是否為 Empty。
public static ReadOnlySpan < T > Empty { get; }
public bool IsEmpty { get; }
屬性值
| 方法 | 屬性值 | 註解 |
|---|---|---|
| Empty | ReadonlySpan < T > | 一個沒有元素的 Span < T > 對象 |
| IsEmpty | bool | 如果 實例 是沒有元素的(不是 null ),返回 true;否則返回 false |
示例
int [ ] ZHSs = [ 1 , 2 ];
int [ ]? ZHSnull = null;
ReadOnlySpan < int > zhsReadOnlySpan = new ( ZHSs );
bool Berkong = zhsReadOnlySpan . IsEmpty;
foreach ( var z in zhsReadOnlySpan )
Console . Write ( $"{z} " ); Console . WriteLine ( $"{( Berkong ? "是" : "不是" )}空的" );
Console . WriteLine ( );
Console . WriteLine ( "下面將 ReadOnlySpan 置空:" );
zhsReadOnlySpan = [ ]; // .NET 推薦簡化形式,其實就是 ReadOnlySpan < int > . Empty
Berkong = zhsReadOnlySpan . IsEmpty;
Console . WriteLine ( $"{zhsReadOnlySpan . ToString ( )} {( Berkong ? "是" : "不是" )}空的" );
Console . WriteLine ( "下面是以 null 數組創建的 ReadOnlySpan:" );
ReadOnlySpan < int > ReadOnlySpannull = new ( ZHSnull );
Berkong = ReadOnlySpannull . IsEmpty;
Console . WriteLine ( $"{ReadOnlySpannull . ToString ( )} {( Berkong ? "是" : "不是" )}空的" );
註解
自 null 數組和 Empty 數組創建的 ReadOnlySpan 均為 0 元素 Span。
ReadOnlySpan . Item [ ] 和 ReadOnlySpan . Length
Item [ 索引 ] 返回 ReadOnlySpan 中指定索引處的元素(引用);Length 返回 ReadOnlySpan 的元素數(長度)。
public ref T this [ int 索引 ] { get; }
public int Length { get; }
屬性值
| 方法 | 類型 | 註解 |
|---|---|---|
| Item | T | 位於指定索引處的元素值(引用) |
| Length | Int32 | ReadOnlySpan 實例的長度 |
異常
| 異常 | 註解 |
|---|---|
| IndexOutOfRangeException | 索引 > 實例 . Length
索引 < 0 |
示例
int [ ] ZHSs = [ 1 , 2 ];
int [ ]? ZHSnull = null;
ReadOnlySpan < int > zhsReadOnlySpan = new ( ZHSs );
Console . WriteLine ( $"自有元素的數組創建的 ReadOnlySpan 的長度:{zhsReadOnlySpan . Length}" );
for ( int z = 0 ; z < zhsReadOnlySpan . Length ; z++ )
Console . WriteLine ( zhsReadOnlySpan [ z ] );
// 置空 ReadOnlySpan
zhsReadOnlySpan = [ ];
Console . WriteLine ( $"數組創建的 ReadOnlySpan 被 Empty 之後的長度:{zhsReadOnlySpan . Length}" );
for ( int z = 0 ; z < zhsReadOnlySpan . Length ; z++ )
Console . WriteLine ( zhsReadOnlySpan [ z ] );
zhsReadOnlySpan = new ( ZHSnull );
Console . WriteLine ( $"空數組創建的 ReadOnlySpan 的長度:{zhsReadOnlySpan . Length}" );
for ( int z = 0 ; z < zhsReadOnlySpan . Length ; z++ )
Console . WriteLine ( zhsReadOnlySpan [ z ] );
方法
ReadOnlySpan . CastUp
將 T派生 的只讀範圍轉換為 T基 的只讀範圍。
public static ReadOnlySpan < T > CastUp < T派生 > ( ReadOnlySpan < T派生 > 項目s ) where T派生 : class, T基;
參數
| 參數 | 類型 | 註解 |
|---|---|---|
| T派生 | 欲轉換的類型(必須為 T基 的派生類型) | |
| 項目s | T派生 | 源只讀範圍,不進行復制 |
| T基 | T派生 的基類型 |
返回值
| 類型 | 註解 |
|---|---|
| ReadOnlySpan < T基 > | 將 項目s 中的 T派生 轉換為 T基 的只讀範圍 |
示例
ReadOnlySpan < LEI派生 > PSs = [ new LEI派生 ( ) , new LEI派生 ( ) ];
// 由於 FF空方法 的參數是 ReadOnlySpan < LEI基 >,需要對 PSs 轉換
ReadOnlySpan < LEI基 > JIs = ReadOnlySpan < LEI基 > . CastUp ( PSs );
FF空方法 ( JIs );
static void FF空方法 ( ReadOnlySpan < LEI基 > 基礎類 )
{
Console . WriteLine ( 基礎類 . ToString ( ) );
}
public class LEI基
{
}
public class LEI派生 : LEI基
{
}
備註
此方法使用協變強制轉換,生成與源共享相同內存的只讀範圍。類型約束中表達的關係確保了該強制轉換是一種安全操作。
Span . CopyTo
將此 Span < T > 的內容複製到目標 Span < T > 中。
public void CopyTo ( Span < T > 目標 );
參數
| 參數 | 類型 | 註解 |
|---|---|---|
| 目標 | Span < T > | 欲複製的目標 Span |
異常
| 異常 | 註解 |
|---|---|
| ArgumentException | 目標 比 實例 短 |
示例
下面這個例程複製了一個 ReadOnlySpan:
int [ ] ZHSs = [ 1 , 2 , 3 ];
ReadOnlySpan < int > ZHSsReadOnlySpan = new ( ZHSs );
Span < int > ZHSsReadOnlySpan複製 = stackalloc int [ ZHSsReadOnlySpan . Length ];
ZHSsReadOnlySpan . CopyTo ( ZHSsReadOnlySpan複製 );
Console . WriteLine ( $"源 ReadOnlySpan:" );
foreach ( var z in ZHSsReadOnlySpan )
Console . Write ( $"{z} " );
Console . WriteLine ( );
Console . WriteLine ( $"目標 Span:" );
foreach ( var z in ZHSsReadOnlySpan複製 )
Console . Write ( $"{z} " );
備註
如果 實例 和 目標 重疊,實例 的全部內容會先被複制到臨時位置,再從臨時位置複製到 目標。
與 Span . CopyTo 不同,Span 的複製行為可能導致數據複製前被覆蓋。
ReadOnlySpan . Equals 和 ReadOnlySpan . GetHashCode
Equals 是比較兩個 ReadOnlySpan 是否相等的方法;GetHashCode 方法返回 實例 的哈希代碼。均不支持。
[ System . Obsolete ( "Equals ( ) on Span will always throw an exception. Use the equality operator instead." ) ]
public override bool Equals ( object? 對象 );
[ System . Obsolete ( "GetHashCode ( ) on Span will always throw an exception." ) ]
public override int GetHashCode ( );
參數
| 參數 | 類型 | 註解 |
| 對象 | object? | 不支持 |
返回值
| 方法 | 類型 | 註解 |
| Equals | bool | 不支持
| GetHashCode | Int32 |不支持 |
異常
| 異常 | 註解 |
| NotSupportedException | 總是不支持這兩個方法 |
Span . GetEnumerator
返回此 ReadOnlySpan < T > 的枚舉器。
public ReadOnlySpan < T > . Enumerator GetEnumerator ( );
參數
| 參數 | 類型 | 註解 |
|---|---|---|
| T | 任意類型 | 返回值中的枚舉器的類型 |
返回值
| 類型 | 註解 |
|---|---|
| ReadOnlySpan < T > . Enumerator | 此 實例 的枚舉器 |
備註
無需直接調用 GetEnumerator 方法,您可以使用 C# 的 foreach 語句以及 Visual Basic 的 For Each … Next 結構來枚舉 ReadOnlySpan < T >。
ReadOnlySpan . Slice
從當前只讀範圍中切分出一個切片,該切片從指定索引開始,可以具有指定長度。
重載
| 重載 | 註解 |
|---|---|
| Slice ( int 起始索引 ) | 自當前只讀範圍 實例 的指定索引處起始的切片Slice |
| ( int 起始索引 , int 元素數 ) | 自當前只讀範圍 實例 的指定索引處起始的切片,具有 元素數 長度 |
public Span < T > Slice ( int 起始索引 );
public Span < T > Slice ( int 起始索引 , int 元素數 );
參數
| 參數 | 類型 | 註解 |
|---|---|---|
| 起始索引
元素數 |
int | 指定切片的起始索引,若不指定 元素數,則切片至 ReadOnlySpan 的末尾 |
返回值
| 類型 | 註解 |
|---|---|
| ReadOnlySpan < T > | 按照指定範圍切片 實例 後的 ReadOnlySpan |
異常
| 異常 | 註解 |
| ArgumentOutOfRangeException | 起始索引 和/或 元素數 < 0
起始索引(或 + 元素數)> 實例 . Length |
示例
int [ ] ZHSs = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ];
ReadOnlySpan < int > ZHSsReadOnlySpan = ZHSs . AsSpan ( );
ReadOnlySpan < int > ReadOnlySpan3 = ZHSsReadOnlySpan [ 3 .. ]; // .NET 推薦使用範圍運算符,實際為 ZHSsReadOnlySpan . Slice ( 3 )
ReadOnlySpan < int > ReadOnlySpan07 = ZHSsReadOnlySpan [ .. 7 ];
ReadOnlySpan < int > ReadOnlySpan25 = ZHSsReadOnlySpan . Slice ( 2 , 5 );
Console . WriteLine ( "ReadOnlySpan3 的元素:" );
Console . WriteLine ( string . Join ( ',' , ReadOnlySpan3 . ToArray ( ) ) );
Console . WriteLine ( "ReadOnlySpan25 的元素:" );
Console . WriteLine ( string . Join ( ',' , ReadOnlySpan25 . ToArray ( ) ) );
Console . WriteLine ( "ReadOnlySpan07 的元素:" );
Console . WriteLine ( string . Join ( ',' , ReadOnlySpan07 . ToArray ( ) ) );
註解
起始索引 從 0 起始。
新版的 .NET 推薦使用範圍運算符替換沒有 元素數 參數或 起始索引 參數為 0 的 Slice(但不推薦替換使用元素數的 Slice,或許 Slice 更易讀):
- ReadOnlySpan [ 3 .. ] == ReadOnlySpan . Slice ( 3 )
- ReadOnlySpan [ .. 7 ] == ReadOnlySpan . Slice ( 0 , 7 )
- ReadOnlySpan [ 2 .. 4 ] == ReadOnlySpan . Slice ( 2 , 2 ) // 不被推薦的替換
Slice 允許返回 Empty ReadOnlySpan,即 起始索引(無 元素數 參數) == 實例 . Length 或 元素數 == 0。
Span . ToArray
將此只讀範圍的內容複製到新數組中。
public T [ ] ToArray ( );
返回值
| 類型 | 註解 |
| T [ ] | 與 Span 實例 相同類型的數組,包含 實例 中的所有元素 |
示例
以下示例展示了 ToArray 方法的實用範圍之一,即 ReadonlySpan 的排序,ReadOnlySpan 沒有 Sort 方法,因為它是隻讀的。可借用 ToArray 方法,對其返回的數組排序,再覆蓋原 ReadOnlySpan,得到已排序的 ReadOnlySpan:
int [ ] ZHSs = [ 10 , 32 , 23 , 74 , 56 , 65 , 7 , 38 ];
ReadOnlySpan < int > ZHSsReadOnlySpan = ZHSs . AsSpan ( );
// 僅處理 ReadOnlySpan,排序它
ZHSs = ZHSsReadOnlySpan . ToArray ( );
Array . Sort ( ZHSs );
ZHSsReadOnlySpan = ZHSs . AsSpan ( );
foreach ( var z in ZHSsReadOnlySpan )
Console . Write ( $"{z} " );
Console . WriteLine ( );
備註
此方法會執行堆分配,因此應儘可能避免使用。在處理數組的 API 中,堆分配是常見的。如果不存在接受 ReadOnlySpan < T > 的替代 API 重載,那麼使用此類 API 就無法避免。
ReadOnlySpan . ToString
返回此 ReadOnlySpan < T > 對象的字符串表示形式。
public override string ToString ( );
返回值
| 類型 | 註解 |
|---|---|
| String | Span 實例 的字符串表示形式 |
示例
請注意 ReadOnlySpan < char > 與其他 ReadOnlySpan 的區別:
int [ ] ZHSs = [ 10 , 32 , 23 , 74 , 56 , 65 , 7 , 38 ];
ReadOnlySpan < int > ZHSsReadOnlySpan = ZHSs . AsSpan ( );
char [ ] ZFs = [ 'a' , 'b' , 'c' ];
ReadOnlySpan < char > ZFsReadOnlySpan = ZFs . AsSpan ( );
string [ ] ZFCs = [ "龍生" , "九子" , "皆非龍" ];
ReadOnlySpan < string > ZFCsReadOnlySpan = ZFCs . AsSpan ( );
Console . WriteLine ( $"ZFsReadOnlySpan . ToString ( ) = {ZFsReadOnlySpan}" );
Console . WriteLine ( $"ZFCsReadOnlySpan . ToString ( ) = {ZFCsReadOnlySpan . ToString ( )}" );
Console . WriteLine ( $"ZHSsReadOnlySpan . ToString ( ) = {ZHSsReadOnlySpan . ToString ( )}" );
備註
對於 ReadOnlySpan < Char >,ToString 方法會返回一個 String,其中包含 ReadOnlySpan < T > 所指向的字符。否則,它會返回一個 String,其中包含該類型的名稱以及 ReadOnlySpan < T > 所包含的元素數量,類似下列格式:
System . Span < 元素類型 > [ 元素數 ]
Span . TryCopyTo
嘗試將當前的 ReadOnlySpan < T > 實例複製到目標 Span < T >,並返回一個指示覆制操作是否成功的值。
public bool TryCopyTo ( Span < T > 目標 );
參數
| 類型 | 註解 |
|---|---|
| Span < T > | 欲將 實例 複製到的目標 Span |
返回值
| 類型 | 註解 |
|---|---|
| bool | 如果複製成功,返回 true,否則返回 false |
示例
bool BerCopy;
int [ ] ZHSs源 = [ 10 , 32 , 23 ] , ZHSs目標 = [ 2 , 8 , 10 ];
ReadOnlySpan < int > ZHSsReadOnlySpan源 = ZHSs源 . AsSpan ( );
Span < int > ZHSsSpan目標 = ZHSs目標 . AsSpan ( );
foreach ( var z in ZHSsSpan目標 )
Console . Write ( $"{z} " );
Console . WriteLine ( );
BerCopy = ZHSsReadOnlySpan源 . TryCopyTo ( ZHSsSpan目標 );
if ( BerCopy )
{
foreach ( var z in ZHSsSpan目標 )
Console . Write ( $"{z} " );
}
else Console . WriteLine ( "複製不成功!" );
Console . WriteLine ( );
int [ ] ZHS4 = [ 4 , 4 , 4 , 4 ];
ZHSsSpan目標 = ZHS4 . AsSpan ( );
foreach ( var z in ZHSsSpan目標 )
Console . Write ( $"{z} " );
Console . WriteLine ( );
BerCopy = ZHSsReadOnlySpan源 . TryCopyTo ( ZHSsSpan目標 );
if ( BerCopy )
{
foreach ( var z in ZHSsSpan目標 )
Console . Write ( $"{z} " );
}
else Console . WriteLine ( "複製不成功!" );
Console . WriteLine ( );
int [ ] ZHS2 = [ 2 , 2 ];
ZHSsSpan目標 = ZHS2 . AsSpan ( );
foreach ( var z in ZHSsSpan目標 )
Console . Write ( $"{z} " );
Console . WriteLine ( );
BerCopy = ZHSsReadOnlySpan源 . TryCopyTo ( ZHSsSpan目標 );
if ( BerCopy )
{
foreach ( var z in ZHSsSpan目標 )
Console . Write ( $"{z} " );
}
else Console . WriteLine ( "複製不成功!" );
備註
TryToCopy 若要返回 true,必須滿足:
實例 的 T 必須與 目標 的 T 相同(否則編譯器即不通過);
實例 的長度必須小於等於 目標 的長度,即:
實例 . Length <= 目標 . Length
如果 實例 和 目標 重疊,則整個 實例 的處理方式就如同先將其複製到臨時位置,再複製到 目標 一樣。
// 即使源和目標重疊,也能正確複製
int [ ] ZHSs = { 1 , 2 , 3 , 4 , 5 };
ReadOnlySpan < int > yuan = array . AsSpan ( 0 , 3 ); // [ 1 , 2 , 3 ]
Span < int > mubiao = array . AsSpan ( 2 , 3 ); // [ 3 , 4 , 5 ]
// 安全複製,不會出現數據損壞
yuan . TryCopyTo ( mubiao ); // ZHSs 變為:[ 1 , 2 , 1 , 2 , 3 ]
當 TryCopyTo 返回 false 時,不會向 目標 寫入任何數據。
運算符
Equality(相等性)
返回一個 bool 值,該值指示兩個 ReadOnlySpan < T > 對象是否相等。
public static bool operator == ( ReadOnlySpan < T > 左 , ReadOnlySpan < T > 右 );
參數
| 參數 | 類型 | 註解 |
|---|---|---|
| 左
右 |
ReadOnlySpan < T > | 欲比較的 ReadOnlySpan 只讀範圍 |
返回值
| 類型 | 註解 |
|---|---|
| bool | 若兩個 ReadOnlySpan < T > 對象相等,返回 true;否則返回 false |
示例
int [ ] array1 = [ 1 , 2 , 3 , 4 , 5 ];
int [ ] array2 = [ 1 , 2 , 3 , 4 , 5 ]; // 內容相同但引用不同
// 創建指向同一數組的 ReadOnlySpan
ReadOnlySpan < int > span1 = array1 . AsSpan ( );
ReadOnlySpan < int > span2 = array1 . AsSpan ( ); // 指向同一數組
// 創建指向不同數組但內容相同的ReadOnlySpan
ReadOnlySpan<int> span3 = array2 . AsSpan ( ); // 指向不同數組但內容相同
// 創建指向同一數組不同部分的 ReadOnlySpan
ReadOnlySpan < int > span4 = array1 . AsSpan ( 0 , 3 ); // [ 1 , 2 , 3 ]
ReadOnlySpan < int > span5 = array1 . AsSpan ( 2 , 3 ); // [ 3 , 4 , 5 ]
Console . WriteLine ( "比較結果:" );
Console . WriteLine ( $"span1 == span2:{span1 == span2}" ); // true - 同一內存
Console . WriteLine ( $"span1 == span3:{span1 == span3}" ); // false - 不同內存
Console . WriteLine ( $"span4 == span5:{span4 == span5}" ); // false - 不同內存區域
// 內容比較(需要手動實現)
bool contentsEqual = span1 . SequenceEqual ( span3 );
Console . WriteLine ( $"span1 . SequenceEqual ( span3 ):{contentsEqual}" ); // true - 內容相同
備註
兩個 ReadOnlySpan < T > 對象相等的條件是它們具有相同的長度,且 左 和 右 的對應元素指向相同的內存。請注意,相等性測試不會嘗試判斷內容是否相等。
Implicit(隱式)
定義數組到 ReadOnlySpan;數組分段(Segment)到 Span 的隱式轉換。
public static implicit operator Span < T > ( T [ ]? 數組 );
public static implicit operator Span < T > ( ArraySegment < T > 分段 );
參數
| 參數 | 類型 | 註解 |
|---|---|---|
| 數組 | T [ ]? | 欲轉換為 ReadOnlySpan < T > 的數組 |
| 分段 | ArraySegment < T > | 欲轉換為 ReadOnlySpan < T > 的數組分段 |
返回值
| 類型 | 註解 |
|---|---|
| ReadOnlySpan < T > | 與 數組 或其片段對應的只讀範圍 |
示例
int [ ] ZHSs = [ 1 , 2 , 3 ];
ReadOnlySpan < int > ZHSsSpan = ZHSs;
string zfc = "倒黴孩子!";
ReadOnlySpan < char > ZFCsSpan = zfc;
ArraySegment < int > PD = new ( ZHSs , 1 , 2 );
ReadOnlySpan < int > ZHSsPDSpan = PD;
foreach ( var z in ZHSsSpan )
Console . Write ( $"{z} " );
Console . WriteLine ( );
foreach ( var z in ZFCsSpan )
Console . Write ( $"{z} " );
Console . WriteLine ( );
foreach ( var z in ZHSsPDSpan )
Console . Write ( $"{z} " );
Console . WriteLine ( );
Inequality(不等性)
返回一個 bool 值,該值指示兩個 ReadOnlySpan < T > 對象是否不相等。
public static bool operator != ( Span < T > 左 , Span < T > 右 );
參數
| 參數 | 類型 | 註解 |
|---|---|---|
| 左
右 |
ReadOnlySpan < T > | 欲比較的 ReadOnlySpan 只讀範圍 |
返回值
| 類型 | 註解 |
|---|---|
| bool | 若兩個 ReadOnlySpan < T > 對象不相等,返回 true;否則返回 false |
示例
int [ ] array1 = [ 1 , 2 , 3 , 4 , 5 ];
int [ ] array2 = [ 1 , 2 , 3 , 4 , 5 ]; // 內容相同但引用不同
// 創建指向同一數組的 ReadOnlySpan
ReadOnlySpan < int > span1 = array1 . AsSpan ( );
ReadOnlySpan < int > span2 = array1 . AsSpan ( ); // 指向同一數組
// 創建指向不同數組但內容相同的ReadOnlySpan
ReadOnlySpan<int> span3 = array2 . AsSpan ( ); // 指向不同數組但內容相同
// 創建指向同一數組不同部分的 ReadOnlySpan
ReadOnlySpan < int > span4 = array1 . AsSpan ( 0 , 3 ); // [ 1 , 2 , 3 ]
ReadOnlySpan < int > span5 = array1 . AsSpan ( 2 , 3 ); // [ 3 , 4 , 5 ]
Console . WriteLine ( "比較結果:" );
Console . WriteLine ( $"span1 == span2:{span1 == span2}" ); // true - 同一內存
Console . WriteLine ( $"span1 == span3:{span1 == span3}" ); // false - 不同內存
Console . WriteLine ( $"span4 == span5:{span4 == span5}" ); // false - 不同內存區域
// 內容比較(需要手動實現)
bool contentsEqual = span1 . SequenceEqual ( span3 );
Console . WriteLine ( $"span1 . SequenceEqual ( span3 ):{contentsEqual}" ); // true - 內容相同
備註
兩個 ReadOnlySpan < T > 對象不等的條件是它們具有不同的長度,且 左 和 右 的對應元素指向不同的內存。