Structure types are kept on the stack. The problem with dynamic is that it's not possible to determine the size of the object it's holding, so how far does the code move the stack pointer so one object or function return doesn't overwrite part of your structure? It's not possible.
You're trying to violate just about every point listed in the ref documentation:
Quote:
Ref struct types
Adding the ref modifier to a struct declaration defines that instances of that type must be stack allocated. In other words, instances of these types can never be created on the heap as a member of another class. The primary motivation for this feature was Span<t> and related structures.
The goal of keeping a ref struct type as a stack-allocated variable introduces several rules that the compiler enforces for all ref struct types.
You can't box a ref struct. You cannot assign a ref struct type to a variable of type object, dynamic, or any interface type.
ref struct types cannot implement interfaces.
You can't declare a ref struct as a field member of a class or a normal struct. This includes declaring an auto-implemented property, which creates a compiler generated backing field.
You cannot declare local variables that are ref struct types in async methods. You can declare them in synchronous methods that return Task, Task<tresult> or Task-like types.
You cannot declare ref struct local variables in iterators.
You cannot capture ref struct variables in lambda expressions or local functions.
These restrictions ensure you don't accidentally use a ref struct in a manner that could promote it to the managed heap.
You can combine modifiers to declare a struct as readonly ref. A readonly ref struct combines the benefits and restrictions of ref struct and readonly struct declarations.