C# ReadonlySpan作为属性

C# ReadonlySpan作为属性,c#,.net-core,C#,.net Core,我试图理解.NETCore3.0。 据我所知,我不能使用Span或ReadonlySpan作为属性或成员,因为它是基于堆栈的结构。 我想知道以下定义之间的区别。 我可以毫无错误地成功定义“part1”。 我收到以下第2部分的编译错误 “Span类型的stackalloc表达式的结果不能在此上下文中使用” 对于第3部分,我收到了不同的编译错误。 “字段或自动实现的属性不能为ReadonlySpan类型” 公共类KeyGenWithSpan { 私有静态ReadOnlySpan part1=>new

我试图理解.NETCore3.0。 据我所知,我不能使用Span或ReadonlySpan作为属性或成员,因为它是基于堆栈的结构。 我想知道以下定义之间的区别。 我可以毫无错误地成功定义“part1”。 我收到以下第2部分的编译错误 “Span类型的stackalloc表达式的结果不能在此上下文中使用” 对于第3部分,我收到了不同的编译错误。 “字段或自动实现的属性不能为ReadonlySpan类型”

公共类KeyGenWithSpan
{
私有静态ReadOnlySpan part1=>new[]{'p','1'};
私有静态ReadOnlySpan part2=>stackalloc[]{'1','2'};
私有静态ReadOnlySpan part3=stackalloc[]{'1','2'};
}
跨度是基于堆栈的结构,但数据可以在任何地方。它可以在数组中,也可以是非托管内存,也可以是堆栈,也可以是“固定缓冲区”或字符串,等等

可以将跨距作为属性。除了在
ref-struct
类型上,您不能将跨度作为字段。该属性将充当代理,从某个对象(可能是数组)获取跨度

第1部分
中,您每次都要分配一个新数组,但这不是必需的,可以更智能地完成

但是,对于
stackalloc
,这是不可能的,因为
stackalloc
将在属性getter的堆栈帧中进行分配,当您退出getter时,该堆栈帧不再存在

考虑:

private static readonly char[]s_data={'p','1'};
public static ReadOnlySpan Data=>s_Data;//完全有效转换

请注意,对于某些类型(特别是:not
char
),编译器可以在此处执行额外的巫术:

publicstaticreadonlyspan-Data2=>新字节[]{0,1};
不在getter中每次编译到新数组;相反,它直接从程序集元数据中提取:

.method public hidebysig specialname static valuetype [System.Runtime]System.ReadOnlySpan`1<uint8> get_Data2() cil managed
{
    .maxstack 8
    L_0000: ldsflda int16 <PrivateImplementationDetails>::3F29546453678B855931C174A97D6C0894B8F546
    L_0005: ldc.i4.2 
    L_0006: newobj instance void [System.Runtime]System.ReadOnlySpan`1<uint8>::.ctor(void*, int32)
    L_000b: ret 
}
.method public hidebysing specialname静态值类型[System.Runtime]System.ReadOnlySpan`1 get_Data2()cil managed
{
.maxstack 8
L_0000:ldsflda int16::3F29546453678B855931C174A97D6C0894B8F546
L_0005:ldc.i4.2
L_0006:newobj实例void[System.Runtime]System.ReadOnlySpan`1::.ctor(void*,int32)
L_000b:ret
}

pedantic point,也许是,但跨距不是.NET Core 3所特有的;它们被移植到更多的框架中(尽管在.NETCore3上实现更好)
.method public hidebysig specialname static valuetype [System.Runtime]System.ReadOnlySpan`1<uint8> get_Data2() cil managed
{
    .maxstack 8
    L_0000: ldsflda int16 <PrivateImplementationDetails>::3F29546453678B855931C174A97D6C0894B8F546
    L_0005: ldc.i4.2 
    L_0006: newobj instance void [System.Runtime]System.ReadOnlySpan`1<uint8>::.ctor(void*, int32)
    L_000b: ret 
}