Ich überarbeite meine Bibliotheken, Span<T>
um Heap-Zuweisungen nach Möglichkeit zu vermeiden, aber da ich auch ältere Frameworks anvisiere, implementiere ich auch einige allgemeine Fallback-Lösungen. Aber jetzt habe ich ein seltsames Problem gefunden und bin mir nicht ganz sicher, ob ich einen Fehler in .NET Core 3 gefunden habe oder ob ich etwas Illegales mache.
Die Angelegenheit:
// 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;
}
Interessanterweise ReinterpretOld
funktioniert es gut in .NET Framework und in .NET Core 2.0 (also könnte ich schließlich damit zufrieden sein), aber es stört mich ein bisschen.
Übrigens. ReinterpretOld
kann auch in .NET Core 3.0 durch eine kleine Änderung behoben werden:
//return *(uint*)bytes;
uint* asUint = (uint*)bytes;
return *asUint;
Meine Frage:
Ist dies ein Fehler oder funktioniert es ReinterpretOld
in älteren Frameworks nur aus Versehen und sollte ich das Update auch für sie anwenden?
Bemerkungen:
- Der Debug-Build funktioniert auch in .NET Core 3.0
- Ich habe versucht, mich zu bewerben
[MethodImpl(MethodImplOptions.NoInlining)]
,ReinterpretOld
aber es hatte keine Wirkung.
stackalloc
(dh er löscht nicht den zugewiesenen Speicherplatz)
return Unsafe.As<byte, uint>(ref bytes[0]);
oderreturn MemoryMarshal.Cast<byte, uint>(bytes)[0];
- keine Notwendigkeit zu verwendenGetPinnableReference()
; Blick in das andere Stück