【问题标题】:c# compiler doesn't resolve generic type parameters by constraints [duplicate]c#编译器不通过约束解析泛型类型参数[重复]
【发布时间】:2019-05-24 23:03:27
【问题描述】:

我有以下用例:

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

现在我想为ServiceCollection 编写一个扩展方法,以便轻松地将我的Endpoints 注册到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>();

    }
}

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

【问题讨论】:

  • 这叫做partial Inference.Net不支持,它是all-or-nothing 外遇。然而,根据你想在这个 兔子洞 中走多远以及你想放松多少 类型安全,你有 hacks可以,但是没有一个是令人满意的
  • 精氨酸。松散=失去
  • @TheGeneral 感谢这个词,我不知道,这就是我写代码的原因)

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


【解决方案1】:

遗憾的是,这不是通用约束/参数的工作方式。您要么指定 NO 泛型类型参数并且编译器推断所有参数,要么指定所有参数。

【讨论】:

    【解决方案2】:

    我的案例最终得到了以下解决方案:

    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>();
    

    【讨论】:

      猜你喜欢
      • 2010-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      相关资源
      最近更新 更多