在以下两个示例中,返回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
参数如何影响(如果有的话)?答案 0 :(得分:1)
这是不安全的,因为不再保证使用stackalloc
分配的内存在函数退出后仍然可用。
在所有这种情况下,您都使用不安全的设施来覆盖警告。使用不安全的代码,您可以做任何您想做的事情。例如,您可以返回不安全的堆栈(int
)上的int x = 0; return &x;
指针。
这不可能是其他方式,因为语言或运行时无法通过这些不安全的设施来跟踪生命周期。即使可以跟踪它,也会破坏stackalloc
的性能优势。 stackalloc
的存储速度很快,因为已知它会在函数退出时释放。