-
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] Add reflection support to byref-like types #10057
Comments
https://github.com/dotnet/corefx/issues/14021
is the bug you’re looking for.
|
Done in dotnet/corefx#28674 |
@ahsonkhan - Any ideas on what an api that allows this would even look like? You can't box Spans, you can't use them as arguments to a generic instantiation, you can't take refs to them (I think) - I'm drawing a blank here. |
This is not Span-specific problem. This is about introducing new reflection APIs that are both fast (do not allocate) and full fidelity (give you full control over byrefs). We have several issues on this topic. We would need to extend TypedReference, and introduce a new type that can hold array of TypedReferences. It may look something like this: // CoreRT has prior art for this. https://github.com/dotnet/corert/search?q=LocalVariableSet
public ref struct TypedReferences
{
public TypedReferences(int length);
public int Length { get; }
public public TypedReference T this[int index] { get; set; }
}
public class MethodInfo
{
public abstract void Invoke(TypedReference returnValue, TypedReferences arguments);
} Use: Span<byte> s1, s2, result;
var args = new TypedReferenceArray(2);
args[0] = new TypedReference(ref s1);
args[1] = new TypedReference(ref s2);
mi.Invoke(new TypedReference(ref result), args); This does not compile today because of several language and runtime restrictions. We would need to fix these restrictions to make this work. This would not be a simple local feature. It would be a set of small features spanning language, runtime and framework. |
Thanks - that's the info I was looking for. |
Related to https://github.com/dotnet/corefx/issues/29990, Activator.CreateInstance boxes the value it returns (since it returns an object). This is not supported for byref types. Should we support this as part of the reflection work? |
Not being able to use Spans as arguments / return values in reflection calls via |
Beyond calling methods on Span or that take Span arguments via reflection, another thing to do is to add overloads to existing reflection APIs to take spans instead of string. For example |
Proposals to spanify existing overloads that take member names should be in its own proposal - I suspect the odds of it getting accepted are low though as
|
Nope, doesn't seem to work. |
We talked about this via phone the other day, but typing it here just so it's not lost. The combination of the proposed methods FromObject and AsRef can be used as an unsafe-equivalent when used to unwrap boxed value types. object boxedBool = false;
TypedReferenced refToBool = TypedReference.FromObject(ref boxedBool);
refToBool.AsRef<bool>() = true; // ECMA violation: mutates boxed value type This would be equivalent to |
The part that bites is that with reflection there is no way to call I could have simply done it as a string, but doing from span -> string to call |
Moving to 9.0. A functional prototype for invoking and passing by-ref like types was created, along with a variable-length, stack-based collection. However, the perf numbers were not that great, so we decided to add new invoke APIs to address the "fast invoke" portion before the byref-like type support. Also, we need to evaluate byref-like type support in the context of loosely-coupled reflection including how byref-like types can be created in a loosely-typed way (today they can't; see the tests in the prototype above). |
This addresses long-standing issues with reflection around support for byref-like types. For additional detail, see
API
Note that these are all new types so the
diff
format was not used for readability.Samples
Avoiding boxing
Value types can be references to avoid boxing.
Pass a
Span<T>
to a methodFuture
For perf, we may add fixed-length parameter storage to MethodInvoker:
along with the supporting type:
with samples:
Fixed-length arguments
Fixed-length object arguments (faster)
Original issue text from @ahsonkhan:
typeof(SpanExtensions).GetMethod("AsReadOnlySpan", new Type[] { typeof(string) }).Invoke(null, new object[] { "Hello" });
fails gracefully.The text was updated successfully, but these errors were encountered: