###### tags: `C#`,`2022` # Span<T> C#7.2新增的功能。 ```csharp= readonly ref struct Span<T> { readonly ref T _pointer; readonly int _length; public ref T this[int index] => ... } ``` _pointer是紀錄記憶體指定的位置 _length 是從這個位置連續存取的長度 Span<T> 是struct結構,ref T支援直接返回引用,這樣就無需通過計算來確定指標開頭、起始偏移,從而真正擁有和訪問陣列一樣高的效率。 這裡有分為Slow Span 和 Fast Span 這裡先記得只有兩個引數(ref本身和長度欄位)稱為Fast Span,原生有支援,操作Get、Set的效能和陣列差不多 ## Stack-Only Span<T>會把資料存放在stack上,靜態分配,有限制大小,會自動釋放記憶體,因此有以下設限 * 不能用在類別的屬性 * 不能在介面上實作 * 不能用在非同步方法的參數 * 不能為泛行參數 * 不能用在Lamnda、iterator ### 非同步應用 Memory<T> 如果想要在非同步應用,可以使用Memory<T>或是ReadOnlyMemory<T>,可存放連續記憶體,並且無限制大小 ## AsSpan() 可以取代Substring(),效能更好更快,個人覺得還滿好用的。 這裡AsSpan()傳出的型別會是ReadOnlySpan<char> ```csharp= var text = "ABCgoogleIEYahoo"; //從第8個字開始取6個位元 var name = text.AsSpan(3, 6); var builder = new StringBuilder("Hi "); builder.Append(name); builder.AppendLine("!"); Console.WriteLine(builder.ToString()); ``` 另一種用法,搭配Slice() 可以達成用逗號區擷取前後數值 ```csharp= var input = "123,456"; var inputSpan = input.AsSpan(); var commaPos = input.IndexOf(','); // no-Allocating, no-Coping var first = int.Parse(inputSpan.Slice(0, commaPos)); var second = int.Parse(inputSpan.Slice(commaPos + 1)); ``` ## 總結 對於字串的處理,Span可以提昇效能,減少浪費 ## Reference [Unserstand Span](https://docs.microsoft.com/zh-tw/events/connect-2017/t125) {%hackmd BJrTq20hE %}