roslyn
                                
                                
                                
                                    roslyn copied to clipboard
                            
                            
                            
                        Hot Reload: Allow extern functions to be added
The [UnsafeAccessorAttribute] (API Proposal) is used on static extern functions to instruct the .NET runtime to generate an accessor method to a type member that bypass the normal .NET visibility checks.
   public class MyClass
   {
      private int _hidden;
      ...
    }
    public static partial class AccessHelpers
    {
        [UnsafeAccessor(UnsafeAccessorKind.Field, Name="_hidden")]
        public static extern ref int GetHiddenField(MyClass c);    // runtime generated implementation
    }
    ...
    public static MyClass DeserializeMyClass(string s)
    {
        MyClass x = new MyClass();
        ref int hiddenFieldRef = ref AccessHelpers.GetHiddenField(x);
        hiddenFieldRef = int.Parse(s);
        return x;
     }    
}
With [UnsafeAccessor] it becomes possible to use source-generated reflection-free serializers that can serialize and deserialize fields of user-defined classes.  For example, a user may add a new field _hidden to MyClass and the source generator will add a new accessor method to AccessHelpers and generate a method DeserializeMyClass that uses the access method to populate the hidden field.
Currently if the user adds a second private field _hidden2 and the generator adds a new static extern method, EnC will report a rude edit:
error ENC0025: Adding an extern method requires restarting the application.
Note that both AccessHelpers or the static extern method could be generic:
public class MyContainer<T>
{
   private T[] _elements;
}
public static AccessHelpers<T>
{
   [UnsafeAccessor(UnsafeAccessorKind.Field, Name="_elements")]
   public static extern ref T[] GetElements(MyContainer<T> container);
}
public static AccessHelpers2
{
   [UnsafeAccessor(UnsafeAccessorKind.Field, Name="_elements")]
   public static extern ref T[] GetElements<T>(MyContainer<T> container);
}
The runtime support is tracked in https://github.com/dotnet/runtime/issues/102080
/cc @tmat
Note these are not P/Invokes.  extern functions dont' have any special flags set.  Instead they just don't have a method body RVA (and thus no method header or IL)
Compare C.PInvoke vs C.StaticExtern vs C.NormalStatic: https://sharplab.io/#v2:EYLgtghglgdgNAFxFANgHwAICYCMBYAKAwAYACDHAOgCUBXGBKMAU0oEkHmAnAewAcAytwBuUAMbMAzgG5ChDAGZyOAGzkspAMKkA3oVIHSAbQAiKFGzB8eXBAAoARAA0AmgC0AMlGAOAlAF19Q0VlNWYADwRuGHIAFlIABQ5hHgBrZjtfWQJDUiCDEIowyOi40gEECEYxAFESrhhM7Nz88iUisoA5G0gUCqrxTN0AX0JhoA