-
Notifications
You must be signed in to change notification settings - Fork 128
Closed
Description
Using the following csproj and code
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>link</TrimMode>
<_ExtraTrimmerArgs>--verbose</_ExtraTrimmerArgs>
</PropertyGroup>
<Target Name="EnsureAllAssembliesAreLinked"
BeforeTargets="PrepareForILLink">
<ItemGroup>
<ManagedAssemblyToLink>
<TrimMode>link</TrimMode>
</ManagedAssemblyToLink>
<TrimmerRootAssembly Include="@(IntermediateAssembly)" />
</ItemGroup>
</Target>
</Project>using System;
class Program
{
static int Main(string[] args)
{
Add((OptionsA a) => Console.Write(a));
return 100;
}
private class OptionsA
{
}
private static void Add<TSource>(Action<TSource> configureSource) where TSource : new()
{
var source = new TSource();
configureSource?.Invoke(source);
}
}- Using the latest .NET 5 SDK
dotnet publish -r win-x64
You get a warning like the following:
F:\DotNetTest\HelloWorld\Program.cs(17,5): Trim analysis warning IL2006: .Program.Add<TSource>(Action<TSource>): The generic parameter 'TSource' from '.Program.Add<TSource>(Action<TSource>)' with dynamically accessed member kinds 'None' is passed into the generic parameter 'T' from 'System.Activator.CreateInstance<T>()' which requires dynamically accessed member kinds 'PublicParameterlessConstructor'. To fix this add DynamicallyAccessedMembersAttribute to it and specify at least these member kinds 'PublicParameterlessConstructor'. [F:\DotNetTest\HelloWorld\HelloWorld.csproj]
This is because the above pattern of where TSource : new() and then calling new TSource(); in code turns into:
private static void Add<TSource>(Action<TSource> configureSource)
where TSource : new()
{
TSource tSource = Activator.CreateInstance<TSource>();
if (configureSource != null)
{
configureSource(tSource);
}
}And the linker sees Activator.CreateInstance<TSource>() but it doesn't see a PublicParameterlessConstructor usage.