Skip to content
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

DynamicallyAccessedMembers does not mark the type if passed in as string #1537

Closed
vitek-karas opened this issue Oct 6, 2020 · 3 comments
Closed

Comments

@vitek-karas
Copy link
Member

The below has to be built into a classlib which is then aggressively trimmed:

namespace lib
{
    public class Test
    {
        public static void TestIt()
        {
            object o = CreateInstanceOf("lib.GenOut`1[[lib.GenIn]]");
            Console.WriteLine(o);
        }

        static object CreateInstanceOf([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] string n)
        {
            return Activator.CreateInstance(Type.GetType(n));
        }
    }


    class GenOut<T> where T : new()
    {
        T GetValue() { return new T(); }
    }

    class GenIn
    {
    }
}

Per annotations, it is perfectly valid to call Activator.CreateInstance due to the annotation on the parameter of CreateInstanceOf. Linker doesn't produce any warnings from the code above.

But when executed, the application fails with:

Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'type')
   at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   at lib.Test.CreateInstanceOf(String n) in F:\ILLinker\repro\TypeNameRep\lib\Class1.cs:line 16
   at lib.Test.TestIt() in F:\ILLinker\repro\TypeNameRep\lib\Class1.cs:line 10
   at Program.Main(String[] args) in F:\ILLinker\repro\TypeNameRep\TypeNameRep\Program.cs:line 17

The failure is because Type.GetType returns null. In the trimmed assembly there's actually no type GenOut.
There are two weird things here:

  1. GenOut<>.ctor() should be kept, but for some reason we leave it out
  2. Even if I force include GenOut<> (by having a direct typeref to it), GenIn also needs to be kept, which won't happen either
@vitek-karas
Copy link
Member Author

Interestingly changing the code to call CreateInstanceOf("lib.GenOut`1") actually works, the GenOut<>.ctor is kept and the app fails because it's invalid to instantiate open generic type.

@vitek-karas
Copy link
Member Author

I also found dotnet/sdk#13999 when working on this bug.

@vitek-karas
Copy link
Member Author

This has been fixed, the repro from the issue above works now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants