Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
新的C#Span<;T>;与排列排序不同<;T>;?_C#_.net Core - Fatal编程技术网

新的C#Span<;T>;与排列排序不同<;T>;?

新的C#Span<;T>;与排列排序不同<;T>;?,c#,.net-core,C#,.net Core,我很难概念化的用法 它取代了什么构造?ArraySegment现在过时了吗 它启用了以前没有的哪些功能 Span是C#阵列的有效替代品吗?在哪些情况下是,在哪些情况下否 何时使用ArraySegment而不是Span 我正试图了解我的编码风格需要如何改变才能有效地利用新的Span。Span并不能取代任何东西。这是增值。它提供了对连续内存段的类型安全视图,这些连续内存段可以以多种不同的方式分配:作为托管阵列、基于堆栈的内存或非托管内存 ArraySegment仅限于托管阵列。您不能使用它来包装使用

我很难概念化的用法

  • 它取代了什么构造?ArraySegment现在过时了吗

  • 它启用了以前没有的哪些功能

  • Span是C#阵列的有效替代品吗?在哪些情况下是,在哪些情况下否

  • 何时使用ArraySegment而不是Span

  • 我正试图了解我的编码风格需要如何改变才能有效地利用新的Span。

    Span
    并不能取代任何东西。这是增值。它提供了对连续内存段的类型安全视图,这些连续内存段可以以多种不同的方式分配:作为托管阵列、基于堆栈的内存或非托管内存

    ArraySegment
    仅限于托管阵列。您不能使用它来包装使用
    stackalloc
    在堆栈上分配的数据
    Span
    允许您这样做

    ArraySegment
    也不提供底层数组的只读视图
    ReadOnlySpan
    为您提供了这一功能

    Span
    不应替换阵列。归根结底,这只是一个数据视图。必须以某种方式分配这些数据,在托管世界中,对于大多数情况,这种分配将是一种数组分配。所以你仍然需要数组

    如果希望代码能够处理的不仅仅是数组,那么应该使用
    Span
    。例如,考虑解析库。现在,为了让它能够处理数组、堆栈分配内存和非托管内存,它必须在API中为每个数组、堆栈分配内存和非托管内存提供多个入口点,并使用不安全的代码来实际操作数据。它可能还需要公开一个基于
    字符串的API,供将数据分配为字符串的人使用。使用
    Span
    ReadOnlySpan
    可以将所有逻辑合并到一个基于
    Span
    的解决方案中,该解决方案将适用于所有这些场景

    Span
    绝对不是每个人都会经常使用的东西。它是.NET framework的一个高度专业化的部分,主要对库作者和非常高性能的关键场景有用。例如,Kestrel,ASP.NET核心背后的web服务将从迁移到
    Span
    中获得许多性能优势,因为例如,可以使用
    Span
    和堆栈分配的内存来解析请求,这对GC没有压力。但是,基于ASP.NET Core编写网站和服务不需要使用它。

    From:Span的定义使得操作与数组上的操作一样高效:索引到Span不需要计算来确定指针的起始位置及其起始偏移量,因为ref字段本身已经封装了这两者(相比之下,ArraySegment有一个单独的偏移量字段,这使得索引和传递成本更高。)


    此外,虽然ArraySegment实现了
    IEnumerable
    ,但Span没有实现

    在决定是否使用C#中的引用结构时,还应考虑以下限制:

    Span是一个ref结构,在堆栈上分配,而不是在 在托管堆上Ref结构类型对 确保它们不能升级到托管堆,包括 它们不能装箱,也不能分配给类型为的变量 对象、动态或任何接口类型,它们不能是 引用类型,它们不能跨等待和屈服使用 边界。另外,调用两个方法,Equals(Object)和 GetHashCode,抛出NotSupportedException。

    重要的

    因为它是一种仅用于堆栈的类型,所以Span不适用于许多应用程序 需要在堆上存储对缓冲区的引用的场景。这 例如,对于进行异步方法调用的例程来说是真的。 对于这种情况,您可以使用免费的系统。内存和 System.ReadOnlyMemory类型

    对于表示不可变或只读结构的跨距,请使用 System.ReadOnlySpan

    将ref修饰符添加到结构声明中可定义该实例 必须为该类型分配堆栈。换言之 这些类型永远不能作为其他类型的成员在堆上创建 班级。此功能的主要动机是广度和相关性 结构

    将ref struct类型保留为堆栈分配变量的目标 介绍编译器对所有ref结构强制执行的几个规则 类型。

    • 您不能框选引用结构。
    • 不能将ref struct类型分配给object、dynamic或任何接口类型的变量。
    • ref结构类型无法实现接口。
    • 不能将ref结构声明为类或普通结构的成员
    • 不能在异步方法中声明ref-struct类型的局部变量。您可以在返回Task、Task或类似Task类型的同步方法中声明它们。
    • 不能在迭代器中声明ref-struct局部变量。
    • 无法在lambda表达式或局部函数中捕获ref struct变量。
    • 这些限制确保您不会意外地使用ref结构,从而将其升级到托管堆。
    可以组合修饰符将结构声明为只读引用a 只读ref结构结合了ref的优点和限制 结构和只读结构声明


    ArraySegment
    是否仅限于某些数据结构的一段(例如数组)?
    Span
    是否限制在相同的范围内