Span<T>
यदि संभव हो तो ढेर आवंटन से बचने के लिए मैं अपने पुस्तकालयों का उपयोग करने के लिए मना कर रहा हूं लेकिन जैसा कि मैंने भी पुराने ढांचे को लक्षित किया है, मैं कुछ सामान्य कमबैक समाधानों को भी लागू कर रहा हूं। लेकिन अब मुझे एक अजीब मुद्दा मिला और मुझे पूरा यकीन नहीं है कि मुझे .NET कोर 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 फ्रेमवर्क और .NET कोर 2.0 में अच्छा काम करता है (इसलिए मैं इसके बाद खुश हो सकता हूं), फिर भी, यह मुझे थोड़ा परेशान करता है।
Btw। ReinterpretOld
एक छोटे संशोधन द्वारा .NET कोर 3.0 में भी तय किया जा सकता है:
//return *(uint*)bytes;
uint* asUint = (uint*)bytes;
return *asUint;
मेरा प्रश्न:
क्या यह एक बग है या ReinterpretOld
केवल दुर्घटना से पुराने ढांचे में काम करता है और क्या मुझे उनके लिए भी फिक्स लागू करना चाहिए?
टिप्पणियों:
- डीबग बिल्ड वर्क्स .NET .NET 3.0 में भी काम करता है
- मैंने आवेदन
[MethodImpl(MethodImplOptions.NoInlining)]
करने की कोशिश कीReinterpretOld
लेकिन इसका कोई असर नहीं हुआ।
stackalloc
(अर्थात यह आवंटित स्थान को मिटा नहीं सकता)
return Unsafe.As<byte, uint>(ref bytes[0]);
याreturn MemoryMarshal.Cast<byte, uint>(bytes)[0];
- उपयोग करने की आवश्यकता नहीं हैGetPinnableReference()
; अन्य बिट में देख हालांकि