Context
To better work with UUID data types in our database, we have written a .NET UUID value type to map these database values to. As a UUID is, essentially, just 16 bytes of binary data (some rules apply as to how this data must be generated and laid out in memory, see RFC 9562), we opted to use the InlineArrayAttribute added with .NET 8 to ensure that our struct is exactly 16 bytes of data. This, to me, seems cleaner than having to specify fields manually and having to deal with struct layouts and endianness. It seems to be the intended use for this attribute. See the simplified minimal reproducible example below:
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
Uuid uuid = Uuid.NewRandom();
string uuidString = uuid.ToString();
Console.WriteLine(uuidString);
[DebuggerDisplay("{ToString(),nq}")]
[InlineArray(16)]
public struct Uuid
{
public byte _element0;
public static Uuid NewRandom()
{
Uuid result = default;
Random.Shared.NextBytes(result.AsSpan());
return result;
}
public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element0, 16);
public override string ToString() => Convert.ToHexString(AsSpan());
}
Based on the InlineArrayAttribute, the runtime allocates enough memory for the struct to store 16 instances of the only struct member (of type byte), thus allocating 16 bytes. In our NewRandom() implementation, we allocate an empty, zero-initialized instance of the UUID, create a Span<byte> over it, and fill that span with random data (for demonstration purposes). In the example, we then call ToString() on it, which correctly returns a 16-byte random hex string.
The “problem” arises when we inspect the Uuid instance using the debugger (Visual Studio 2022, Version 17.10.1) as seen below:
As can be seen, only the first byte (the only “actual” field) of the UUID is correctly displayed in the debugger view. All other fields are set to 0.
It seems this is only an issue while debugging. The runtime behavior of the structure seems to be as it should be. Still, I wonder why the behavior of ToString() is different when used in DebuggerDisplayAttribute as compared to calling it within program execution?
So my question is as follows:
Does this indicate an issue with the UUID implementation itself (i.e., am I doing something wrong?), or is it “merely” a bug in the current version of Visual Studio with a rarely used combination of attributes?
I did not find any official reference online indicating an incompatibility of these attributes.
The Show raw structure of objects in variables window option in Visual Studio is disabled, so DebuggerDisplayAttribute should work (see https://learn.microsoft.com/en-us/visualstudio/debugger/using-the-debuggerdisplay-attribute?view=vs-2022)
