如果可能,我正在重构我的库以Span<T>
用于避免堆分配,但由于我还针对较旧的框架,我也在实施一些通用的后备解决方案。但是现在我发现了一个奇怪的问题,我不太确定我是否在 .NET Core 3 中发现了一个错误,或者我是否在做一些非法的事情。
问题:
// This returns 1 as expected but cannot be used in older frameworks:
private static uint ReinterpretNew()
{
Span<byte> bytes = stackalloc byte[4];
bytes[0] = 1; // FillBytes(bytes);
// returning bytes as uint:
return Unsafe.As<byte, uint>(ref bytes.GetPinnableReference());
}
// This returns garbage in .NET Core 3.0 with release build:
private static unsafe uint ReinterpretOld()
{
byte* bytes = stackalloc byte[4];
bytes[0] = 1; // FillBytes(bytes);
// returning bytes as uint:
return *(uint*)bytes;
}
有趣的是,ReinterpretOld
它在 .NET Framework 和 .NET Core 2.0 中运行良好(所以我毕竟对它感到满意),但它仍然让我有些困扰。
顺便提一句。ReinterpretOld
也可以通过小修改在 .NET Core 3.0 中修复:
//return *(uint*)bytes;
uint* asUint = (uint*)bytes;
return *asUint;
我的问题:
这是一个错误还是ReinterpretOld
只是偶然在较旧的框架中起作用,我应该也为它们应用修复程序吗?
评论:
- 调试版本也适用于 .NET Core 3.0
- 我试图申请
[MethodImpl(MethodImplOptions.NoInlining)]
,ReinterpretOld
但没有效果。