-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: GCHandle.GetTargetUnsafe() with no handle validation #94113
Comments
Notably this suggestion came from the perspective that the current implementation is logically: ThrowIfInvalid(handle);
handle &= ~(nuint)(1); // strip the pin bit
return InternalGet(handle); This means that these two calls should be logically the same, but they aren't: GCHandle.FromIntPtr(0).Target; // InvalidOperation
GCHandle.FromIntPtr(1).Target; // NullReference We're already handling all kinds of invalid handles and most of them, outside |
Tagging subscribers to this area: @dotnet/interop-contrib Issue DetailsBackground and motivation
This proposal is about adding a way to get the handle target with no branches, when callers know no validation is needed. API Proposalnamespace System.Runtime.InteropServices;
public struct GCHandle
{
+ public readonly object? GetTargetUnsafe();
} API Usage// In a constructor (or wherever)
this.handle = GCHandle.Alloc(myObj);
// Later on
object? target = this.handle.GetTargetUnsafe(); Alternative DesignsAlternatively (as @tannergooding also suggested), we could instead just remove the validation check from The benefit of this approach is that no new API is needed, and everyone "gets faster for free". RisksWith the new API, no risk.
|
There are other similar inefficiencies in GCHandle:
And there is the cosmetic issue of GCHandle not implementing IDisposable (#54792). We should consider all of them at the same time. We may want to consider introducing a new type that has all of them fixed. |
That type looks really nice 👀 If there is interest, what about opening a new proposal for that, linking all these ones, and try to get that to API review? |
Superseded by #94134, closing this. |
Background and motivation
GCHandle
is often used in scenarios (such as handwritten COM objects, or other interop setups) where callers have complete control over the handles, and nobody else is ever mutating them. The only way, currently, to get a target, is to useGCHandle.Target
, which always incurs in a validation check, which is pretty much always just useless branching in these cases.This proposal is about adding a way to get the handle target with no branches, when callers know no validation is needed.
API Proposal
namespace System.Runtime.InteropServices; public struct GCHandle { + public readonly object? GetTargetUnsafe(); }
API Usage
Alternative Designs
Alternatively (as @tannergooding also suggested), we could instead just remove the validation check from
GCHandle.Target
. This would technically be a breaking change, as it would cause invalid handles to throw aNullReferenceException
instead of anInvalidOperationException
, but it might be considered acceptable in this scenario, since it's a niche API.The benefit of this approach is that no new API is needed, and everyone "gets faster for free".
Risks
With the new API, no risk.
With the alternate design, people taking a hard dependency on that exception type would break.
The text was updated successfully, but these errors were encountered: