-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Description
To support ref struct with reflection (invoking and passing), the current 8.0 runtime plan for "safe" code is to leverage the existing TypedReference type to create and obtain ref struct references through the existing __makeref and __refvalue keywords.
In addition, TypedReference, being a stack-only construct, was added in 1.0 well before ref struct support (or byref-like types) and currently has more restricted compiler semantics than ref struct causing various limitations such as the inability to use ref struct as a field. This has been discussed as fixing or sunsetting "restricted types" in
https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/low-level-struct-improvements.md but this has not yet been addressed. See also #64811. cc @jaredpar
An alternative to supporting __makeref\__refvalue\__reftype with ref struct but much more expensive, is to support generic method parameters for ref struct. This could be added in the future and new static methods added to TypedReference to support that. However, based on prior discussions, adding support for __makeref et al. would be much easier for now.
Misc prototyping in the roslyn repro to remove the various compiler restrictions shows the 8.0 .NET runtime seems to handle the changes fine. Whether the runtime needs a new "feature switch" should be discussed -- I assume most runtimes, if they support ref struct and TypedReference and __makeref et al., should work as-is without additional work. cc @AaronRobinsonMSFT @jkotas
Version Used:
MSBuild17.4.0+18d5aef85 (C# 11)
Steps to Reproduce:
Sample code that repro some of the restricted usages of TypedReference but are valid with ref structs such as Span<object>.:
Console.WriteLine("Hello, World!");
Span<object> obj = default;
TypedReference tr = __makeref(obj); // CS1601: Cannot make reference to variable of type 'Span<object>'
public class MyClass
{
public TypedReference _field; // CS0610: Field or property cannot be of type 'TypedReference'
public TypedReference CallMe() => default; // CS1599: The return type of a method, delegate, or function pointer cannot be 'TypedReference'
public void CallMe(ref TypedReference tr) {} // CS1601: Cannot make reference to variable of type 'TypedReference' error CS1601
}Related Links: