Examine the following code.
class Program
{
delegate void TestMeDelegate(Span<byte> data);
static void Main(string[] args)
{
TestMeDelegate testMeDelegate = TestMe;
Action<Span<byte>> testMeAction = TestMe;
}
static void TestMe(Span<byte> data)
{
}
}
The row using testMeDelegate works, but the row using testMeAction throws
The type '
Span<byte>' may not be used as a type argument
I am targeting.net 4.7.2 with the System.Memory nuget version 4.5.1
Langversion is set to C# latest minor version (latest) should be 7.3
Questions:
Is this simply a compiler bug?
What are the differences between Action and delegate in this scenario?
It's exactly as the error describes.
The
Span<T>type is aref struct, meaning it's storage location can only be on the stack (So not on the heap). The compiler will output diagnostics for cases were this can't be guaranteed.The problem is that the compiler can't determine this with generics. Although there are some situations that the compiler could detect (like yours), the compiler team has decided not to allow
ref structtypes to be used as generic types at all.I don't know the exact reasoning why they don't properly check this for generic types, but some I can imagine are: