C#编译器无法通过约束来解析通用类型参数

时间:2019-05-24 23:03:28

标签: c# generics generic-type-argument nested-generics

我有以下用例:

我在ASP.NET Core WebAPi项目中创建了通用端点结构。

现在我想向ServiceCollection写一个扩展方法,以方便地将我的Endpoint注册到DI。

现在,我将尝试演示我想要的东西。 假设我们有:

interface IEndPoint<TInput, TOutput>
{
    TOutput Execute(TInput input);
}

class StrToIntEndPoint : IEndPoint<string, int>
{
    public int Execute(string input)
    {
        return int.Parse(input);
    }
}

class ServiceCollection { }

static class ServiceCollectionServiceExtensions
{
    public static void AddScoped<TService, TImplementation>(this ServiceCollection services) where TImplementation : TService
    {

    }
}

static class MyCustomExt
{
    // Here, I have to add TInput, TOutput type parameters to AddEndpoint method too.
    public static void AddEndpoint<T, TInput, TOutput>(this ServiceCollection services) where T: IEndPoint<TInput, TOutput>
    {
        services.AddScoped<IEndPoint<TInput, TOutput>, T>();
    }
}

class Program
{
    static void Main()
    {
        var services = new ServiceCollection();

        // Compile Error: Incorrect number of type parameters
        services.AddEndpoint<StrToIntEndPoint>();

        // fine
        services.AddEndpoint<StrToIntEndPoint, string, int>();

    }
}

我的问题是为什么编译器不会通过引用stringintAddEndpoint解析为StrToIntEndPoint的类型参数?

2 个答案:

答案 0 :(得分:1)

遗憾的是,这并不是通用约束/参数的工作方式。您可以不指定任何泛型类型参数,然后编译器会推断所有参数,或者您可以指定所有参数。

答案 1 :(得分:1)

针对我的情况,我最终得到了以下解决方案:

static class MyCustomExt
{
    public static IServiceCollection AddScopedWitInterfaces<T>(this IServiceCollection services)
    {
        Type type = typeof(T);

        Type[] interfaces = type.GetInterfaces();

        foreach (Type interfaceType in interfaces)
        {
            services.AddScoped(interfaceType, type);
        }

        return services;
    }
}

然后在ConfigureServices中注册我的服务:

services.AddScopedWitInterfaces<StrToIntEndpoint>();