当前位置: 首页 > ds >正文

C# Span 入门

本文简单告诉大家如何使用 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 指定数组的某一段

            var array = new byte[10];Span<byte> bytes = array; bytes = bytes.Slice(start: 2, length: 5);bytes[0] = 5;Console.WriteLine(array[2]);Console.WriteLine(bytes[0]);

可以看到对 bytes[0] 的修改就是对 array[2] 的修改,这样可以做到数组重新计算。

也就是对某个计算,需要加上数组的移动,如二维数组的图片计算,例如行是 w 列是 h ,那么计算第 n 行的元素,在以前的时候,就需要在每个的前面加上 w*n,现在可以使用 spanList.Slice(start:w*n, Length:w) 这样重新拿到的数组就是一行,不需要在每个计算都需要添加很多代码

            var array = new byte[10];Span<byte> bytes = array; bytes = bytes.Slice(start: 2, length: 5);bytes[0] = 5;Console.WriteLine(array[2]);Console.WriteLine(bytes[0]);try{bytes[5] = 2;}catch (IndexOutOfRangeException e){Console.WriteLine(e);}

有了这个类就不需要担心写出超过范围代码

stackalloc

如果要和 stackalloc 需要打开不安全代码

然后点击生成高级,选择 C# 7.2 以上

现在可以写出这样的代码

        private static unsafe void DroosorHotir(){Span<byte> bytes = stackalloc byte[2];bytes[0] = 2;bytes[1] = 3;Console.WriteLine(bytes[0]);Console.WriteLine(bytes[1]);}

调用这个函数可以输出 2 和 3 ,使用 stackalloc 可以比申请数组使用更少的资源。因为默认申请的数组都在堆中,不使用需要 gc 才可以回收。但是 stackalloc 可以在变量所在函数结束之后直接就回收,不需要移动内存。

但是 stackalloc 容易出现堆栈溢出,请执行下面的代码,堆栈溢出是 catch 也无法让他不让程序直接退出

            Span<double> bytes = stackalloc double[200000];

即使使用 catch ,软件也会直接退出

            try{Span<double> bytes = stackalloc double[200000];}catch (Exception){// 接不住}

AllocHGlobal

除了使用 stackalloc 之外,还可以使用 Marshal.AllocHGlobal 申请一段内存

            IntPtr ptr = Marshal.AllocHGlobal(2);try{var bytes = new Span<byte>((byte*) ptr, 2) {[0] = 42};Console.WriteLine(bytes[0]);Console.WriteLine(Marshal.ReadByte(ptr));}finally{Marshal.FreeHGlobal(ptr);}

需要注意,申请的内存都需要自己释放

而且需要注意,不要使用比自己申请的内存大的数组

            IntPtr ptr = Marshal.AllocHGlobal(2);var bytes = new Span<byte>((byte*) ptr, 1000) {[0] = 42};

上面代码申请了内存为 2 但是下一句使用了1000长度

                for (int i = 0; i < 1000; i++){bytes[i] = 25;Console.WriteLine(bytes[i]);}

这时虽然很多次都可以赋值成功,但是运行到某个时候,软件就直接退出。

http://www.xdnf.cn/news/11398.html

相关文章:

  • Extjs多标签关闭,支持关闭左侧和右侧标签。
  • 黑客是如何攻破一个网站的?
  • oracle常见问题、了解知识点及简单命令学习
  • 开源文档管理软件KnowledgeTree安装
  • Openbravo ERP介绍(一)
  • 分享88个ASP整站程序源码,总有一款适合您
  • 黑客是怎么通过IP地址攻击的?
  • Linux共享磁盘分区,linux中ISCSI(网络共享磁盘)
  • Windows server——部署web服务
  • 关于代理服务器的原理及用法
  • 通信线路通信线路
  • ping命令详解
  • No message found under code 'world' for locale 'en_US'.
  • [小技巧] 用搜索引擎查找博客中的内容
  • Dynamips报错及及非正常现象的解决办法汇总
  • RFID-射频识别技术
  • 推荐一些漂亮的Ubuntu 9.04主题
  • 汇编语言 --寄存器-指令集-寻址
  • InstallShield12豪华版破解版下载|InstallShield下载|软件打包工具
  • 数据中台与数据治理服务方案[50页PPT]
  • MySQL中的EXISTS用法
  • 一起学UCOS(三)、创建任务
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • QingBlog|轻博客 一个轻量级的Web版个人博客产品
  • 滤波器设计软件--filter solutions的使用
  • 数字信号处理实验二:时域采样与频域采样
  • 用VB操作Excel(VB6.0)(整理)
  • hao123电脑版主页_软件 | 流氓软件网站植入主页一览
  • 八数码与十五数码问题
  • Zencart网站搭建与配置教程