Saya refactoring perpustakaan saya untuk digunakan Span<T>
untuk menghindari alokasi tumpukan jika mungkin tetapi karena saya juga menargetkan kerangka kerja yang lebih tua saya menerapkan beberapa solusi cadangan umum juga. Tapi sekarang saya menemukan masalah aneh dan saya tidak yakin apakah saya menemukan bug di .NET Core 3 atau saya melakukan sesuatu yang ilegal.
Masalah:
// 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;
}
Cukup menarik, ReinterpretOld
bekerja dengan baik di .NET Framework dan .NET Core 2.0 (jadi saya bisa senang dengan itu semua), masih, itu sedikit mengganggu saya.
Btw. ReinterpretOld
dapat diperbaiki juga di .NET Core 3.0 dengan modifikasi kecil:
//return *(uint*)bytes;
uint* asUint = (uint*)bytes;
return *asUint;
Pertanyaan saya:
Apakah ini bug atau ReinterpretOld
bekerja dalam kerangka kerja lama hanya secara tidak sengaja dan haruskah saya menerapkan perbaikannya juga untuk mereka?
Catatan:
- Membangun debug bekerja juga di .NET Core 3.0
- Saya mencoba menerapkan
[MethodImpl(MethodImplOptions.NoInlining)]
untukReinterpretOld
tetapi tidak berpengaruh.
stackalloc
(yaitu tidak menghapus ruang yang dialokasikan)
return Unsafe.As<byte, uint>(ref bytes[0]);
ataureturn MemoryMarshal.Cast<byte, uint>(bytes)[0];
- tidak perlu digunakanGetPinnableReference()
; melihat ke dalam bit lainnya,