-
Notifications
You must be signed in to change notification settings - Fork 483
Add support for by-ref-like (ref struct) parameter types such as Span<T> and ReadOnlySpan<T> #712
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
Conversation
75d36f1 to
34dde0e
Compare
34dde0e to
9abd5df
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This TODO needs to be implemented so we can return by-ref-like values, too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we'll probably be adding a documentation page regarding by-ref-like values during interception, perhaps we could add exception messages with a link to the documentation page for more info...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should implement ConstructorInfo caching here, as the "todo" comment suggest.
Since Span<T> and ReadOnlySpan<T> are commonly encountered types in the FCL, perhaps constructed generic types deriving from these should also be in the cache.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative to calling IInvocation.GetArgumentValue would be to query IInvocation.Arguments once, and then access the returned arguments array directly for every by-ref-like parameter? That might be more efficient for methods having more than one by-ref-like-typed parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implement this "todo" for by-ref-like-typed return parameter support. And don't forget to also Invalidate the wrapper object for the return type.
...roxy` interfaces
* Calling `ByRefLikeProxy` et al. "proxies" could be misleading, since DynamicProxy proxies typically have the exact same public surface as the proxied types. This is not the case here, `ByRefLikeProxy` types come with their own distinct API. I am choosing "reference" because that's exactly what the types are. Alternatives considered were "value accessor" and "argument". The former would lead to long type names (`ByRefLikeValueAccessor`), and the latter would be inaccurate once we start using these types for `IInvocation.ReturnValue`, too. * There seems to be little benefit to having a parallel interface type hierarchy. On the contrary: users observing (say) a `SpanProxy` inst- ance in the debugger and then being told in an XML documentation comment to access it through the `ISpanProxy` interface doesn't seem particularly user-friendly. Let's go with the simplest solution: keep only the classes.
9abd5df to
095ab6c
Compare
Uh oh!
There was an error while loading. Please reload this page.
Unlike my earlier draft #664, this PR will not require DynamicProxy user code to set up any value converters for byref-like parameters.
Instead, any by-ref-like argument will automatically get substituted in
IInvocationwith a "reference" type:(削除)SpanArgument<T>(削除ここまで)(削除)SpanProxy<T>(削除ここまで)SpanReference<T>forSpan<T>values(削除)ReadOnlySpanArgument<T>(削除ここまで)(削除)ReadOnlySpanProxy<T>(削除ここまで)ReadOnlySpanReference<T>forReadOnlySpan<T>values(削除)ByRefLikeProxy(削除ここまで)ByRefLikeReferenceon .NET 8 for any non-span by-ref-like values(削除)ByRefLikeArgument<TByRefLike>(削除ここまで)(削除)ByRefLikeProxy<TByRefLike>(削除ここまで)ByRefLikeReference<TByRefLike>on .NET 9+ for any non-span by-ref-like values of typeTByRefLikeEach of these (except the non-generic
ByRefLikeReference) has aref-returningValueproperty for accessing the actual value.These class types are essentially references to the actual by-ref-like parameters. They use unmanaged pointers (
void*) under the hood. I've added a big comment in theByRefLikeReference.cscode file explaining why I think this is safe.I'm not quite done yet:
MethodWithInvocationGenerator.cs)ByRefLikeTestCase(which still expect by-ref-like parameters to default / get nullified)IInvocationref/contract files and the changelogWill fix #651 and close #663 once completed and merged.