本文简单告诉大家如何使用 Span 新的功能 需要知道 Span 是 7.2 才有的功能,如果在正式项目使用,建议安装 Nuget 的方式
在对内存指定的一段的处理,原来的 C# 是比较弱的,因为没有了 C++ 的指针,特别是对于字符串的分割,需要创建多几个字符串。
垃圾微软为了提高 C# 的性能,于是提供了新的类型 Span,这个类可以拿出任意数组的一段,作为一个新的 Span 列表。这样的底层就是指针,而且指针是有判断是否超过范围比 C++ 安全。
首先安装 Nuget System.Memory 库,要求 dotnet framework 4.5 以上,在 UWP 16299 以上,在 dotnet core 2.0 以上
先来写一个简单的程序,创建一个数组,然后使用 Span 指定数组的某一段
可以看到对 bytes[0] 的修改就是对 array[2] 的修改,这样可以做到数组重新计算。
也就是对某个计算,需要加上数组的移动,如二维数组的图片计算,例如行是 w 列是 h ,那么计算第 n 行的元素,在以前的时候,就需要在每个的前面加上 w*n
,现在可以使用 spanList.Slice(start:w*n, Length:w)
这样重新拿到的数组就是一行,不需要在每个计算都需要添加很多代码
有了这个类就不需要担心写出超过范围代码
stackalloc
如果要和 stackalloc 需要打开不安全代码
然后点击生成高级,选择 C# 7.2 以上
现在可以写出这样的代码
调用这个函数可以输出 2 和 3 ,使用 stackalloc 可以比申请数组使用更少的资源。因为默认申请的数组都在堆中,不使用需要 gc 才可以回收。但是 stackalloc 可以在变量所在函数结束之后直接就回收,不需要移动内存。
但是 stackalloc 容易出现堆栈溢出,请执行下面的代码,堆栈溢出是 catch 也无法让他不让程序直接退出
即使使用 catch ,软件也会直接退出
AllocHGlobal
除了使用 stackalloc 之外,还可以使用 Marshal.AllocHGlobal
申请一段内存
需要注意,申请的内存都需要自己释放
而且需要注意,不要使用比自己申请的内存大的数组
上面代码申请了内存为 2 但是下一句使用了1000长度
这时虽然很多次都可以赋值成功,但是运行到某个时候,软件就直接退出。
参考:
C# - All About Span: Exploring a New .NET Mainstay
通俗易懂,C#如何安全、高效地玩转任何种类的内存之Span(一)
原文链接: http://blog.lindexi.com/post/C-Span-%E5%85%A5%E9%97%A8
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。 欢迎转载、使用、重新发布,但务必保留文章署名 林德熙 (包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我 联系。