我尝试了解 .net core 3.0。据我所知,我不能使用 Span 或 ReadonlySpan 作为属性或成员,因为它是基于堆栈的结构。我想知道以下定义之间的区别。我可以成功定义“part1”而没有任何错误。对于第 2 部分,我收到以下编译错误“Span 类型的 stackalloc 表达式的结果不能在此上下文中使用” 对于第 3 部分,我收到了不同的编译错误。“字段或自动实现的属性不能是 ReadonlySpan 类型”
public class KeyGenWithSpan
{
private static ReadOnlySpan<char> part1 => new[] { 'p', '1'};
private static ReadOnlySpan<char> part2 => stackalloc[]{'1','2'};
private static ReadOnlySpan<char> part3 = stackalloc[]{'1','2'};
}
Run Code Online (Sandbox Code Playgroud)
该范围是一个基于堆栈的结构,但数据可以在任何地方。它可以在数组中,可以是非托管内存,可以是堆栈,可以是“固定缓冲区”或字符串等。
您可以将跨度作为属性。除了类型之外,您不能拥有 span 作为fieldsref struct。该属性将充当从某物(可能是数组)获取跨度的代理。
在 中part1,您每次都分配一个新数组,但这不是必需的 - 可以更智能地完成。
然而,这对 来说是不可能的stackalloc,因为stackalloc会在属性 getter 的 stack-frame 中分配,当您退出 getter 时它不再存在。
考虑:
private static readonly char[] s_data = { 'p', '1'};
public static ReadOnlySpan<char> Data => s_data; // perfectly valid conversion
Run Code Online (Sandbox Code Playgroud)
请注意,对于某些类型(特别是: not char),编译器可以在这里做额外的伏都教:
public static ReadOnlySpan<byte> Data2 => new byte[] { 0, 1 };
Run Code Online (Sandbox Code Playgroud)
每次在 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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1254 次 |
| 最近记录: |