Skip to content

Linker warns about generic type flown into lambda method #1416

@eerhardt

Description

@eerhardt

This is similar to #1403, but instead of generated fields, it is for generic types that are flown into lambda methods.

using System;
using System.Diagnostics.CodeAnalysis;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Create<Person>();
        }

        static Func<T> Create<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T>()
        {
            return () =>
            {
                return Method<T>();   
            };
        }

        static T Method<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T>()
        {
            return Activator.CreateInstance<T>();
        }
    }

    public class Person
    {
        public int Age { get; set; }
    }
}

Produces warning:

F:\DotNetTest\HelloWorld\Program.cs(16,13): Trim analysis warning IL2006: ConsoleApp1.Program.<>c__1<T>.<Create>b__1_0(): The generic parameter 'T' from 'ConsoleApp1.Program.<>c__1<T>' with dynamically accessed member kinds 'None' is passed into the generic parameter 'T' from 'ConsoleApp1.Program.Method<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 was exposed by the following code:

https://github.com/dotnet/runtime/blob/6072e4d3a7a2a1493f514cdf4be75a3d56580e84/src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/HttpClientBuilderExtensions.cs#L330-L345

        internal static IHttpClientBuilder AddTypedClientCore<TClient>(this IHttpClientBuilder builder, bool validateSingleType)
            where TClient : class
        {
            ReserveClient(builder, typeof(TClient), builder.Name, validateSingleType);


            builder.Services.AddTransient<TClient>(s =>
            {
                IHttpClientFactory httpClientFactory = s.GetRequiredService<IHttpClientFactory>();
                HttpClient httpClient = httpClientFactory.CreateClient(builder.Name);


                ITypedHttpClientFactory<TClient> typedClientFactory = s.GetRequiredService<ITypedHttpClientFactory<TClient>>();
                return typedClientFactory.CreateClient(httpClient);
            });


            return builder;
        }

Where ITypedHttpClientFactory<TClient> is annotated with PublicConstructors on TClient.

We should flow the generic type annotations into these methods.

cc @MichalStrehovsky @sbomer @marek-safar @vitek-karas

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions