ArraySegment<T> 結構
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
分隔一維陣列的區段。
generic <typename T>
public value class ArraySegment : System::Collections::Generic::ICollection<T>, System::Collections::Generic::IEnumerable<T>, System::Collections::Generic::IList<T>, System::Collections::Generic::IReadOnlyCollection<T>, System::Collections::Generic::IReadOnlyList<T>
generic <typename T>
public value class ArraySegment
public struct ArraySegment<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>
public readonly struct ArraySegment<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>
[System.Serializable]
public struct ArraySegment<T>
[System.Serializable]
public struct ArraySegment<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>
type ArraySegment<'T> = struct
interface ICollection<'T>
interface seq<'T>
interface IEnumerable
interface IList<'T>
interface IReadOnlyCollection<'T>
interface IReadOnlyList<'T>
[<System.Serializable>]
type ArraySegment<'T> = struct
[<System.Serializable>]
type ArraySegment<'T> = struct
interface IList<'T>
interface ICollection<'T>
interface IReadOnlyList<'T>
interface IReadOnlyCollection<'T>
interface seq<'T>
interface IEnumerable
[<System.Serializable>]
type ArraySegment<'T> = struct
interface IList<'T>
interface ICollection<'T>
interface seq<'T>
interface IEnumerable
interface IReadOnlyList<'T>
interface IReadOnlyCollection<'T>
type ArraySegment<'T> = struct
interface IList<'T>
interface ICollection<'T>
interface IReadOnlyList<'T>
interface IReadOnlyCollection<'T>
interface seq<'T>
interface IEnumerable
Public Structure ArraySegment(Of T)
Implements ICollection(Of T), IEnumerable(Of T), IList(Of T), IReadOnlyCollection(Of T), IReadOnlyList(Of T)
Public Structure ArraySegment(Of T)
類型參數
- T
陣列區段中專案的型別。
- 繼承
- 屬性
- 實作
範例
下列程式代碼範例會將 ArraySegment<T> 結構傳遞至 方法。
using namespace System;
namespace Sample
{
public ref class SampleArray
{
public:
static void Work()
{
// Create and initialize a new string array.
array <String^>^ words = {"The", "quick", "brown",
"fox", "jumps", "over", "the", "lazy", "dog"};
// Display the initial contents of the array.
Console::WriteLine("The first array segment"
" (with all the array's elements) contains:");
PrintIndexAndValues(words);
// Define an array segment that contains the entire array.
ArraySegment<String^> segment(words);
// Display the contents of the ArraySegment.
Console::WriteLine("The first array segment"
" (with all the array's elements) contains:");
PrintIndexAndValues(segment);
// Define an array segment that contains the middle five
// values of the array.
ArraySegment<String^> middle(words, 2, 5);
// Display the contents of the ArraySegment.
Console::WriteLine("The second array segment"
" (with the middle five elements) contains:");
PrintIndexAndValues(middle);
// Modify the fourth element of the first array
// segment
segment.Array[3] = "LION";
// Display the contents of the second array segment
// middle. Note that the value of its second element
// also changed.
Console::WriteLine("After the first array segment"
" is modified,the second array segment"
" now contains:");
PrintIndexAndValues(middle);
Console::ReadLine();
}
static void PrintIndexAndValues(ArraySegment<String^>^ segment)
{
for (int i = segment->Offset;
i < (segment->Offset + segment->Count); i++)
{
Console::WriteLine(" [{0}] : {1}", i,
segment->Array[i]);
}
Console::WriteLine();
}
static void PrintIndexAndValues(array<String^>^ words)
{
for (int i = 0; i < words->Length; i++)
{
Console::WriteLine(" [{0}] : {1}", i,
words[i]);
}
Console::WriteLine();
}
};
}
int main()
{
Sample::SampleArray::Work();
return 0;
}
/*
This code produces the following output.
The original array initially contains:
[0] : The
[1] : quick
[2] : brown
[3] : fox
[4] : jumps
[5] : over
[6] : the
[7] : lazy
[8] : dog
The first array segment (with all the array's elements) contains:
[0] : The
[1] : quick
[2] : brown
[3] : fox
[4] : jumps
[5] : over
[6] : the
[7] : lazy
[8] : dog
The second array segment (with the middle five elements) contains:
[2] : brown
[3] : fox
[4] : jumps
[5] : over
[6] : the
After the first array segment is modified, the second array segment now contains:
[2] : brown
[3] : LION
[4] : jumps
[5] : over
[6] : the
*/
using System;
public class SamplesArray {
public static void Main() {
// Create and initialize a new string array.
String[] myArr = { "The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" };
// Display the initial contents of the array.
Console.WriteLine( "The original array initially contains:" );
PrintIndexAndValues( myArr );
// Define an array segment that contains the entire array.
ArraySegment<string> myArrSegAll = new ArraySegment<string>( myArr );
// Display the contents of the ArraySegment.
Console.WriteLine( "The first array segment (with all the array's elements) contains:" );
PrintIndexAndValues( myArrSegAll );
// Define an array segment that contains the middle five values of the array.
ArraySegment<string> myArrSegMid = new ArraySegment<string>( myArr, 2, 5 );
// Display the contents of the ArraySegment.
Console.WriteLine( "The second array segment (with the middle five elements) contains:" );
PrintIndexAndValues( myArrSegMid );
// Modify the fourth element of the first array segment myArrSegAll.
myArrSegAll.Array[3] = "LION";
// Display the contents of the second array segment myArrSegMid.
// Note that the value of its second element also changed.
Console.WriteLine( "After the first array segment is modified, the second array segment now contains:" );
PrintIndexAndValues( myArrSegMid );
}
public static void PrintIndexAndValues( ArraySegment<string> arrSeg ) {
for ( int i = arrSeg.Offset; i < (arrSeg.Offset + arrSeg.Count); i++ ) {
Console.WriteLine( " [{0}] : {1}", i, arrSeg.Array[i] );
}
Console.WriteLine();
}
public static void PrintIndexAndValues( String[] myArr ) {
for ( int i = 0; i < myArr.Length; i++ ) {
Console.WriteLine( " [{0}] : {1}", i, myArr[i] );
}
Console.WriteLine();
}
}
/*
This code produces the following output.
The original array initially contains:
[0] : The
[1] : quick
[2] : brown
[3] : fox
[4] : jumps
[5] : over
[6] : the
[7] : lazy
[8] : dog
The first array segment (with all the array's elements) contains:
[0] : The
[1] : quick
[2] : brown
[3] : fox
[4] : jumps
[5] : over
[6] : the
[7] : lazy
[8] : dog
The second array segment (with the middle five elements) contains:
[2] : brown
[3] : fox
[4] : jumps
[5] : over
[6] : the
After the first array segment is modified, the second array segment now contains:
[2] : brown
[3] : LION
[4] : jumps
[5] : over
[6] : the
*/
open System
// Print functions.
let printIndexAndValues (myArr: string []) =
for i = 0 to myArr.Length - 1 do
printfn $" [{i}] : {myArr[i]}"
printfn ""
let printIndexAndValuesSeg (arrSeg: ArraySegment<string>) =
for i = arrSeg.Offset to arrSeg.Offset + arrSeg.Count - 1 do
printfn $" [{i}] : {arrSeg.Array[i]}"
printfn ""
// Create and initialize a new string array.
let myArr = [| "The"; "quick"; "brown"; "fox"; "jumps"; "over"; "the"; "lazy"; "dog" |]
// Display the initial contents of the array.
printfn "The original array initially contains:"
printIndexAndValues myArr
// Define an array segment that contains the entire array.
let myArrSegAll = ArraySegment<string>(myArr)
// Display the contents of the ArraySegment.
printfn "The first array segment (with all the array's elements) contains:"
printIndexAndValuesSeg myArrSegAll
// Define an array segment that contains the middle five values of the array.
let myArrSegMid = ArraySegment<string>(myArr, 2, 5)
// Display the contents of the ArraySegment.
printfn "The second array segment (with the middle five elements) contains:"
printIndexAndValuesSeg myArrSegMid
// Modify the fourth element of the first array segment myArrSegAll.
myArrSegAll.Array[3] <- "LION"
// Display the contents of the second array segment myArrSegMid.
// Note that the value of its second element also changed.
printfn "After the first array segment is modified, the second array segment now contains:"
printIndexAndValuesSeg myArrSegMid
(*
This code produces the following output.
The original array initially contains:
[0] : The
[1] : quick
[2] : brown
[3] : fox
[4] : jumps
[5] : over
[6] : the
[7] : lazy
[8] : dog
The first array segment (with all the array's elements) contains:
[0] : The
[1] : quick
[2] : brown
[3] : fox
[4] : jumps
[5] : over
[6] : the
[7] : lazy
[8] : dog
The second array segment (with the middle five elements) contains:
[2] : brown
[3] : fox
[4] : jumps
[5] : over
[6] : the
After the first array segment is modified, the second array segment now contains:
[2] : brown
[3] : LION
[4] : jumps
[5] : over
[6] : the
*)
Public Class SamplesArray
Public Shared Sub Main()
' Create and initialize a new string array.
Dim myArr As String() = {"The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"}
' Display the initial contents of the array.
Console.WriteLine("The original array initially contains:")
PrintIndexAndValues(myArr)
' Define an array segment that contains the entire array.
Dim myArrSegAll As New ArraySegment(Of String)(myArr)
' Display the contents of the ArraySegment.
Console.WriteLine("The first array segment (with all the array's elements) contains:")
PrintIndexAndValues(myArrSegAll)
' Define an array segment that contains the middle five values of the array.
Dim myArrSegMid As New ArraySegment(Of String)(myArr, 2, 5)
' Display the contents of the ArraySegment.
Console.WriteLine("The second array segment (with the middle five elements) contains:")
PrintIndexAndValues(myArrSegMid)
' Modify the fourth element of the first array segment myArrSegAll.
myArrSegAll.Array(3) = "LION"
' Display the contents of the second array segment myArrSegMid.
' Note that the value of its second element also changed.
Console.WriteLine("After the first array segment is modified, the second array segment now contains:")
PrintIndexAndValues(myArrSegMid)
End Sub
Public Shared Sub PrintIndexAndValues(arrSeg As ArraySegment(Of String))
Dim i As Integer
For i = arrSeg.Offset To (arrSeg.Offset + arrSeg.Count - 1)
Console.WriteLine(" [{0}] : {1}", i, arrSeg.Array(i))
Next i
Console.WriteLine()
End Sub
Public Shared Sub PrintIndexAndValues(myArr as String())
Dim i As Integer
For i = 0 To (myArr.Length - 1)
Console.WriteLine(" [{0}] : {1}", i, myArr(i))
Next i
Console.WriteLine()
End Sub
End Class
'This code produces the following output.
'
'The original array initially contains:
' [0] : The
' [1] : quick
' [2] : brown
' [3] : fox
' [4] : jumps
' [5] : over
' [6] : the
' [7] : lazy
' [8] : dog
'
'The first array segment (with all the array's elements) contains:
' [0] : The
' [1] : quick
' [2] : brown
' [3] : fox
' [4] : jumps
' [5] : over
' [6] : the
' [7] : lazy
' [8] : dog
'
'The second array segment (with the middle five elements) contains:
' [2] : brown
' [3] : fox
' [4] : jumps
' [5] : over
' [6] : the
'
'After the first array segment is modified, the second array segment now contains:
' [2] : brown
' [3] : LION
' [4] : jumps
' [5] : over
' [6] : the
備註
ArraySegment<T> 是陣列的包裝函式,可分隔該陣列中的項目範圍。 多個 ArraySegment<T> 實例可以參考相同的原始數位,而且可以重疊。 原始數位必須是一維,而且必須具有以零起始的索引。
注意
ArraySegment<T> 實作從 .NET Framework 4.6 開始的 IReadOnlyCollection<T> 介面;在舊版 .NET Framework 中,ArraySegment<T> 結構並未實作這個介面。
每當陣列元素在相異區段中操作時,ArraySegment<T> 結構就很有用。 例如:
您可以將只代表陣列一部分的 ArraySegment<T> 對象當做自變數傳遞至方法,而不是呼叫相對昂貴的方法,例如 Copy 傳遞數位部分的複本。
在多線程應用程式中,您可以使用 ArraySegment<T> 結構讓每個線程只對陣列的一部分運作。
針對以工作為基礎的異步操作,您可以使用 ArraySegment<T> 對象,確保每個工作在陣列的不同區段上運作。 下列範例會將陣列分成最多十個元素的個別區段。 區段中的每個元素都會乘以其區段編號。 結果顯示,使用 ArraySegment<T> 類別以這種方式操作元素會變更其基礎陣列的值。
using System; using System.Collections.Generic; using System.Threading.Tasks; public class Example { private const int segmentSize = 10; public static async Task Main() { List<Task> tasks = new List<Task>(); // Create array. int[] arr = new int[50]; for (int ctr = 0; ctr <= arr.GetUpperBound(0); ctr++) arr[ctr] = ctr + 1; // Handle array in segments of 10. for (int ctr = 1; ctr <= Math.Ceiling(((double)arr.Length)/segmentSize); ctr++) { int multiplier = ctr; int elements = (multiplier - 1) * 10 + segmentSize > arr.Length ? arr.Length - (multiplier - 1) * 10 : segmentSize; ArraySegment<int> segment = new ArraySegment<int>(arr, (ctr - 1) * 10, elements); tasks.Add(Task.Run( () => { IList<int> list = (IList<int>) segment; for (int index = 0; index < list.Count; index++) list[index] = list[index] * multiplier; } )); } try { await Task.WhenAll(tasks.ToArray()); int elementsShown = 0; foreach (var value in arr) { Console.Write("{0,3} ", value); elementsShown++; if (elementsShown % 18 == 0) Console.WriteLine(); } } catch (AggregateException e) { Console.WriteLine("Errors occurred when working with the array:"); foreach (var inner in e.InnerExceptions) Console.WriteLine("{0}: {1}", inner.GetType().Name, inner.Message); } } } // The example displays the following output: // 1 2 3 4 5 6 7 8 9 10 22 24 26 28 30 32 34 36 // 38 40 63 66 69 72 75 78 81 84 87 90 124 128 132 136 140 144 // 148 152 156 160 205 210 215 220 225 230 235 240 245 250
open System open System.Threading.Tasks // Create array. let arr = Array.init 50 (fun i -> i + 1) // Handle array in segments of 10. let tasks = Array.chunkBySize 10 arr |> Array.mapi (fun m elements -> let mutable segment = ArraySegment<int>(arr, m * 10, elements.Length) task { for i = 0 to segment.Count - 1 do segment[i] <- segment[i] * (m + 1) } :> Task) try Task.WhenAll(tasks).Wait() let mutable i = 0 for value in arr do printf $"{value, 3} " i <- i + 1 if i % 18 = 0 then printfn "" with :? AggregateException as e -> printfn "Errors occurred when working with the array:" for inner in e.InnerExceptions do printfn $"{inner.GetType().Name}: {inner.Message}" // The example displays the following output: // 1 2 3 4 5 6 7 8 9 10 22 24 26 28 30 32 34 36 // 38 40 63 66 69 72 75 78 81 84 87 90 124 128 132 136 140 144 // 148 152 156 160 205 210 215 220 225 230 235 240 245 250
Imports System.Collections.Generic Imports System.Threading.Tasks Module Example Private Const SegmentSize As Integer = 10 Public Sub Main() Dim tasks As New List(Of Task) ' Create array. Dim arr(49) As Integer For ctr As Integer = 0 To arr.GetUpperBound(0) arr(ctr) = ctr + 1 Next ' Handle array in segments of 10. For ctr As Integer = 1 To CInt(Math.Ceiling(arr.Length / segmentSize)) Dim multiplier As Integer = ctr Dim elements As Integer = If((multiplier - 1) * 10 + segmentSize > arr.Length, arr.Length - (multiplier - 1) * 10, segmentSize) Dim segment As New ArraySegment(Of Integer)(arr, (ctr - 1) * 10, elements) tasks.Add(Task.Run( Sub() Dim list As IList(Of Integer) = CType(segment, IList(Of Integer)) For index As Integer = 0 To list.Count - 1 list(index) = list(index) * multiplier Next End Sub )) Next Try Task.WaitAll(tasks.ToArray()) Dim elementsShown As Integer = 0 For Each value In arr Console.Write("{0,3} ", value) elementsShown += 1 If elementsShown Mod 18 = 0 Then Console.WriteLine() Next Catch e As AggregateException Console.WriteLine("Errors occurred when working with the array:") For Each inner As Exception In e.InnerExceptions Console.WriteLine("{0}: {1}", inner.GetType().Name, inner.Message) Next End Try End Sub End Module ' The example displays the following output: ' 1 2 3 4 5 6 7 8 9 10 22 24 26 28 30 32 34 36 ' 38 40 63 66 69 72 75 78 81 84 87 90 124 128 132 136 140 144 ' 148 152 156 160 205 210 215 220 225 230 235 240 245 250
不過請注意,雖然 ArraySegment<T> 結構可用來將數位分割成不同的區段,但區段並不完全獨立於彼此。 Array 屬性會傳回整個原始數位,而不是陣列的複本;因此,對 Array 屬性所傳回之陣列所做的變更,會對原始陣列進行變更。 如果這是不想要的,您應該在數位復本上執行作業,而不是代表陣列一部分的 ArraySegment<T> 物件。
Equals 方法和等號比較兩個 ArraySegment<T> 物件時,會測試參考相等運算符。 若要將兩個 ArraySegment<T> 對象視為相等,它們必須符合下列所有條件:
參考相同的陣列。
從陣列中的相同索引開始。
擁有相同數目的專案。
如果您想要依 ArraySegment<T> 物件中的索引擷取專案,您必須將它轉換成 IList<T> 物件,並使用 IList<T>.Item[] 屬性加以擷取或修改。 請注意,F# 中不需要此專案。 下列範例會擷取 ArraySegment<T> 物件中的專案,此物件會分隔字串陣列的區段。
using System;
using System.Collections.Generic;
public class Example
{
public static void Main()
{
String[] names = { "Adam", "Bruce", "Charles", "Daniel",
"Ebenezer", "Francis", "Gilbert",
"Henry", "Irving", "John", "Karl",
"Lucian", "Michael" };
var partNames = new ArraySegment<string>(names, 2, 5);
// Cast the ArraySegment object to an IList<string> and enumerate it.
var list = (IList<string>) partNames;
for (int ctr = 0; ctr <= list.Count - 1; ctr++)
Console.WriteLine(list[ctr]);
}
}
// The example displays the following output:
// Charles
// Daniel
// Ebenezer
// Francis
// Gilbert
open System
let names =
[| "Adam"; "Bruce"; "Charles"; "Daniel"
"Ebenezer"; "Francis"; "Gilbert"
"Henry"; "Irving"; "John"; "Karl"
"Lucian"; "Michael" |]
let partNames = ArraySegment<string>(names, 2, 5)
// Enumerate over the ArraySegment object.
for part in partNames do
printfn $"{part}"
// The example displays the following output:
// Charles
// Daniel
// Ebenezer
// Francis
// Gilbert
Imports System.Collections.Generic
Module Example
Public Sub Main()
Dim names() As String = { "Adam", "Bruce", "Charles", "Daniel",
"Ebenezer", "Francis", "Gilbert",
"Henry", "Irving", "John", "Karl",
"Lucian", "Michael" }
Dim partNames As New ArraySegment(Of String)(names, 2, 5)
' Cast the ArraySegment object to an IList<String> and enumerate it.
Dim list = CType(partNames, IList(Of String))
For ctr As Integer = 0 To list.Count - 1
Console.WriteLine(list(ctr))
Next
End Sub
End Module
' The example displays the following output:
' Charles
' Daniel
' Ebenezer
' Francis
' Gilbert
建構函式
ArraySegment<T>(T[]) |
初始化 ArraySegment<T> 結構的新實例,這個實例會分隔指定數位中的所有專案。 |
ArraySegment<T>(T[], Int32, Int32) |
初始化 ArraySegment<T> 結構的新實例,這個實例會分隔指定數位中專案的指定範圍。 |
屬性
Array |
取得原始數位,其中包含數位區段分隔的項目範圍。 |
Count |
取得以數位區段分隔之範圍中的項目數目。 |
Empty |
表示空陣組區段。 此欄位是唯讀的。 |
Item[Int32] |
取得或設定位於指定索引處的專案。 |
Offset |
取得陣列區段所分隔之範圍中第一個專案的位置,相對於原始陣列的開頭。 |
方法
CopyTo(ArraySegment<T>) |
將這個實體的內容複製到相同類型的指定目的地陣列區段, |
CopyTo(T[]) |
將這個實體的內容複製到相同型別的指定目的地陣列中, |
CopyTo(T[], Int32) |
從指定的目的地索引開始,將這個實例的內容複製到相同類型的指定目的地陣列 |
Equals(ArraySegment<T>) |
判斷指定的 ArraySegment<T> 結構是否等於目前的實例。 |
Equals(Object) |
判斷指定的物件是否等於目前的實例。 |
GetEnumerator() |
傳回列舉值,可用來逐一查看數位區段。 |
GetHashCode() |
傳回目前實例的哈希碼。 |
Slice(Int32) |
從指定的索引開始,從目前數位區段形成配量。 |
Slice(Int32, Int32) |
從指定的索引開始,形成目前數位區段所指定長度的配量。 |
ToArray() |
將這個陣列區段的內容複製到新的數位中。 |
運算子
Equality(ArraySegment<T>, ArraySegment<T>) |
指出兩個 ArraySegment<T> 結構是否相等。 |
Implicit(T[] to ArraySegment<T>) |
定義類型陣列的隱含轉換, |
Inequality(ArraySegment<T>, ArraySegment<T>) |
指出兩個 ArraySegment<T> 結構是否不相等。 |
明確介面實作
ICollection<T>.Add(T) |
在所有情況下擲回 NotSupportedException 例外狀況。 |
ICollection<T>.Clear() |
在所有情況下擲回 NotSupportedException 例外狀況。 |
ICollection<T>.Contains(T) |
判斷陣列區段是否包含特定值。 |
ICollection<T>.CopyTo(T[], Int32) |
從指定的陣列索引開始,將陣列區段的專案複製到陣列。 |
ICollection<T>.IsReadOnly |
取得值,這個值表示陣列區段是否為唯讀。 |
ICollection<T>.Remove(T) |
在所有情況下擲回 NotSupportedException 例外狀況。 |
IEnumerable.GetEnumerator() |
傳回逐一查看陣列區段的列舉值。 |
IEnumerable<T>.GetEnumerator() |
傳回逐一查看陣列區段的列舉值。 |
IList<T>.IndexOf(T) |
決定陣列區段中特定專案的索引。 |
IList<T>.Insert(Int32, T) |
在所有情況下擲回 NotSupportedException 例外狀況。 |
IList<T>.Item[Int32] |
取得或設定位於指定索引處的專案。 |
IList<T>.RemoveAt(Int32) |
在所有情況下擲回 NotSupportedException 例外狀況。 |
IReadOnlyList<T>.Item[Int32] |
取得位於陣列區段指定索引處的專案。 |