A wired dead end of ref struct (BlobBuilderArray)

While the story begins with BlobBuilderArray which is a ref struct.
public unsafe ref struct BlobBuilderArray<T> where T : struct{...}
I’m working on a Fluent Blob data builder for my BehaviourTree.
Basically, I want to

BolbAssetReference<BehaviourArchetypeBlob> archetype=
BehaviourArchetypeBlob.Initialize()
.Compositor(NodeType.Sequence)
.Action(A)
.Action(B).Build()

So I want my builder to return ref this. C# does not allow it.
But as my Builder is unmanaged. And should only be used on the stack. I can do
fixed(Builder* pThis=&this){ return ref *pThis;}
So far so good.
When my Builder type grows, it will contain some generic type field. And the compiler stopped allowing me to use Builder* although it is unmanaged.
But UnsafeUtility.AddressOf and AsRef can help me walk around that problem.
The return became
return ref UnsafeUtility.AsRef<Builder>(UnsafeUtility.AddressOf<Builder>(ref this))
Still working.
Then I found I need to keep a copy of BlobBuilderArray in my Builder. It’s a ref struct so my Builder needs to be a ref struct to hold a BlobBuilderArray.
Suddenly everything breaks.
The compiler does not agree my Builder is unmanaged so Builder* is baned.
The compiler does not allow ref struct to be a generic type parameter so AddressOf and AsRef is also baned.

What?..

Waite, ref struct is unmanaged and lives only on stack. What’s the problem of simply return ref this for ref struct at all?

As I know it is C# limitation that is fixed in C# 8 :slight_smile:
https://github.com/dotnet/csharplang/issues/1744

And you can enable C#8 even in Unity 2019.4 if you wish
https://github.com/mob-sakai/CSharpCompilerSettingsForUnity

1 Like

Okay, so fixed(Builder* pThis=&this){ return ref *pThis;} is going to work.
but return ref this of ref struct is still not possiable

Do I understood you right?
6440633--720806--upload_2020-10-21_14-39-8.png

Yes. Exactly.
What I mean is fixed(Builder* pThis=&this){ return ref *pThis;} workaround will work in c#8.

I am currently using another walkaround. All data in my Builder type is allocated on heap via Allocator.Temp. So I can freely pass my Builder with or without ref.

return ref this from a ref struct is the real deal, but it has a long way to go…
I started this.
https://github.com/dotnet/csharplang/discussions/4046#discussion-26767