I've edited your code example so that it can actually reproduce the error.
The issue here is that, while the struct
appears to be a legal unmanaged type, by nesting it in a generic type, it becomes a "constructed type", which is considered to be a managed type. This is because the full type of your struct
actually includes the type parameter and generic types are always managed types. I.e. the type isn't just MyStruct
, but rather a.b<T>.MyStruct
where T
is some type.
From the C# 5 language specification, "10.3.8.6 Nested types in generic classes":
Every type declaration contained within a generic class declaration is implicitly a generic type declaration.
"4.4 Constructed types" reads:
A type-name might identify a constructed type even though it doesn’t specify type parameters directly. This can occur where a type is nested within a generic class declaration, and the instance type of the containing declaration is implicitly used for name lookup…In unsafe code, a constructed type cannot be used as an unmanaged-type.
And from "18.2 Pointer types":
…the referent type of a pointer must be an unmanaged-type.
An unmanaged-type is any type that isn’t a reference-type or constructed type, and doesn’t contain reference-type or constructed type fields at any level of nesting.
In other words, the language specification makes it clear both that MyStruct
is a "constructed type", and that you aren't allowed to have pointers to constructed types.
As for why the specification makes these restrictions, I'm not the language designer and so I can't provide a definitive answer on that. However, to me it seems safe to assume that the main issue here is that for a constructed type, it is theoretically possible for the type to not be verifiable at compile type as being safe for unsafe
code.
In your example, the type parameter T
is not used in MyStruct
. But it could be, and that would be obviously bad in the unsafe
pointer context.
I intuitively would guess that it's theoretically possible for the compiler to do additional analysis to verify MyStruct
can be treated as a strictly unmanaged type, but a) I could easily be wrong about that (language designers and compiler writers know a lot more about what could go wrong in situations like this than I would), and b) even if it's theoretically possible, it would be an additional and significant complication in the language specification and the writing of any C# compiler.
That latter point is IMHO justification enough for the language designers to just rule it out. After all, many if not most types nested in a generic type would be using the generic type parameter anyway, so the usefulness of such additional analysis and leniency is probably limited.