以下 2 个返回Span<byte>
(Span<T>
更一般(的示例是否安全,因为当方法返回时,返回的Span<T>
点实例的内存位置仍然包含有意义的数据:
static class Example {
public static void Main() {
var n = 0x0102030405060708U;
var n_bytes_as_span_of_byte = n.ToBytesExtension();
var n2 = 0x8899aabbccddeeffU; // <- will this "overwrite" span-contents above?
//Do something with both n2 and n_bytes_as_span_of_byte...
//Do something with StackAllocExtensions
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Span<byte> ToBytesExtension(
this ulong num // <- Will making it 'ref' make any difference: 'this ref ulong num'?
) => new Span<byte>( // <- Will returning it by 'ref' make any difference: ... => ref ...?
Unsafe.AsPointer(ref num) // <- What if we use '&num' instead of 'Unsafe.AsPointer(ref num)'
, sizeof(ulong));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Span<byte> StackAllocExtensionThatDoesNotCompile(ulong someArg) {
Span<byte> span = stackalloc byte[16];
//Do something with span and someArg...
return span; // <- Does not work: Cannot use local 'span' in this context because it may expose referenced variables outside of their declaration scope.
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Span<byte> StackAllocExtensionThatCompiles(ulong someArg) {
var byte_pointer = stackalloc byte[16];
//Do something with span and someArg...
return new Span<byte>(byte_pointer, 16); // <- But isn't this the same as above? I.e. "exposes referenced variables outside of their declaration scope"?
}
}
也:
- 使用
ref return
和ref
参数对此有何影响(如果有的话(? - 内联有什么区别吗?
这是不安全的,因为在函数退出后,使用stackalloc
分配的内存不再保证可用。
在编译此文件的所有情况下,您都使用了不安全的工具来覆盖警告。使用不安全的代码,您可以做任何您想做的事情。例如,您可以返回指向堆栈上int
的指针(int x = 0; return &x;
(,这同样不安全。
它不能是任何其他方式,因为语言或运行时无法通过这些不安全的设施跟踪生存期。即使它可以跟踪它,它也会破坏stackalloc
的性能优势。stackalloc
内存速度很快,因为已知它在函数退出时释放。