|
|
|
|
|
by orphea
13 days ago
|
|
This attribute makes the compiler generate IL code as if the target member was accessible to the user code. It's orthogonal to AoT and reflection. This works perfectly fine with AoT: var writeLine = typeof(Console).GetMethod("WriteLine", [typeof(string)]);
writeLine.Invoke(null, ["Hello world"]);
As you can see, there are no UnsafeAccessorAttribute's. Plain old reflection that just works (why should it not?)https://godbolt.org/z/Yv8hadYqv |
|
I definitely don't fully understand the landscape, so I could certainly be wrong, but I assumed that normal reflection didn't work in AOT because after trimming that method may or may not be there. If it was never called in a normal way then the compiler doesn't know that `Console.WriteLine` was being used as `GetMethod` may have a runtime value as a string rather than a constant value known at compile time. If the compiler didn't know it was being called then it will be trimmed out of the final binary whereas with `UnsafeAccessorAttribute` it provides the information required to not trim it.
Edit: I tried the following https://sharplab.io/#v2:D4AQTAjAsAUCAMACEEB0AlApgMwDaYGMAXAS... and it fails when I provide the type and method for Console.WriteLine as arguments. If I was to add `typeof(Console).GetMethod(args[1], [typeof(string)])!.Invoke(null, ["dummy"]);` to it before the `Type.GetType` call it seems to be enough to not trim out the `Console` type and the `WriteLine` method. The compiler seems to at least be smart that way.