Skip to content

Enhance by-ref struct argument reference API#741

Open
zvirja wants to merge 8 commits intocastleproject:masterfrom
zvirja:enhance-ref-struct-api
Open

Enhance by-ref struct argument reference API#741
zvirja wants to merge 8 commits intocastleproject:masterfrom
zvirja:enhance-ref-struct-api

Conversation

@zvirja
Copy link

@zvirja zvirja commented Mar 19, 2026

This PR follows up and addresses the issues discussed in #663. I implemented the last proposal and suggest to incorporate it to the initial API. It all looks good to me and I don't see any safety issues with this revision of the API.

Tasks:

  • Throw better and nicer exceptions
  • Allow to access reference value from the original thread only
  • Introduce awareness of the scoped lifetime arguments and track it.
    I expose flag via ByRefLikeReferenceUnsafe, as libraries might be interested in checking it. I hide it from "main" API as it's a very niche check and it might be confusing to the direct consumers.
  • Introduce GetValue/UseValue and SetValue
    • UseValue() could be used for any reference. It's just a bit inconvenient and more restrictive
    • GetValue() could be used only if value is not scoped (which shall be vast majority of the cases)
    • SetValue() requires a lambda, so that we could be sure that local stack-based value could not be leaked. Compiler will guarantee safety, as lambda could be invoked at any time.
  • Introduce ByRefLikeReferenceUnsafe class and hide all the unawanted API there, while making the original API internal. It allows to get rid of public IDE-hidden API with warnings in the doc, as now the API is simply not immediately visible. If you are using Unsafe class - the name kind of implies that you are knowing what you are doing.
  • Cover code with unit tests
  • Update documentation

I also applied a few cosmetic changes:

  • Use void* type to store the ptr - looks nicer
  • Rename Invalidate() to Dispose() - as that's exactly what it is
  • Remove GetPtrNocheck() and use GetPtr() - simpler code + adds better visibility

Feel free to play with the code and apply the necessary changes. My PR is just a proposal.

I could help with the documentation before merge if we agree what it's what we are going with. Didn't want to invest time if we decide to discard it all (which would be sad :-/).

FYI @stakx

P.S. MethodInvocationExpression API is really confusing. I would expect that ctor overload without instance would imply a static method call - not the implicit this call. Took me quite a while to figure out what's going on.

zvirja added 8 commits March 16, 2026 21:07
Do not use Volatile anymore, as code is single-threaded now.
Also use void* to simplify code
By it's nature Unsafe methods are not a part of the "client" API,
so we just provide it on a side and should no longer hide methods/constructors
from user. Also unsafe API is internal on the original class, so it's not immediately
visible to the users.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant