C# 8.0 添加和增强的功能【基础篇】( 四 )


List<int> numbers = null;int? i = null;numbers ??= new List<int>();numbers.Add(i ??= 17);numbers.Add(i ??= 20);Console.WriteLine(string.Join(" ", numbers));// output: 17 17Console.WriteLine(i);// output: 17十二、非托管构造类型在 C# 7.3 及更低版本中,构造类型(包含至少一个类型参数的类型)不能为非托管类型 。从 C# 8.0 开始,如果构造的值类型仅包含非托管类型的字段,则该类型不受管理 。
public struct Coords<T>{public T X;public T Y;}// Coords<int> 类型为 C# 8.0 及更高版本中的非托管类型// 与任何非托管类型一样,可以创建指向此类型的变量的指针,或针对此类型的实例在堆栈上分配内存块Span<Coords<int>> coordinates = stackalloc[]{new Coords<int> { X = 0, Y = 0 },new Coords<int> { X = 0, Y = 3 },new Coords<int> { X = 4, Y = 0 }};Span 简介
??在定义中,Span 就是一个简单的值类型 。它真正的价值,在于允许我们与任何类型的连续内存一起工作 。
??在使用中,Span 确保了内存和数据安全 , 而且几乎没有开销 。
??要使用 Span , 需要设置开发语言为 C# 7.2 以上,并引用System.Memory到项目 。
??Span 使用时,最简单的,可以把它想象成一个数组,有一个Length属性和一个允许读写的index
// 常用的一些定义、属性和方法Span(T[] array);Span(T[] array, int startIndex);Span(T[] array, int startIndex, int length);unsafe Span(void* memory, int length);int Length { get; }ref T this[int index] { get; set; }Span<T> Slice(int start);Span<T> Slice(int start, int length);void Clear();void Fill(T value);void CopyTo(Span<T> destination);bool TryCopyTo(Span<T> destination);// 从 T[] 到 Span 的隐式转换char[] array = new char[] { 'i', 'm', 'p', 'l', 'i', 'c', 'i', 't' };Span<char> fromArray = array;// 复制内存int Parse(ReadOnlySpan<char> anyMemory);int Copy<T>(ReadOnlySpan<T> source, Span<T> destination);??

推荐阅读