泛型类型约束-我可以在方法级别扩展类约束吗?

时间:2019-11-26 16:44:03

标签: c# .net .net-core

我正在开发一种流畅的API,该API可以轻松地在IoC容器中注册所有必需的类。例如:

builder
    .WithInput<EncryptedMessage>()
    .UseEncryptedMessageParser()
    // ...
    // .OtherEncryptedMessageFlowRegistrations()

builder
    .WithInput<StandardMessage>()
    .UseStandardMessageParser()
    // ...
    // .OtherStandardMessageFlowRegistrations()

我想要实现的是在开始时具有不太严格的泛型类型约束,但是在层次结构的后面则使其更加严格。因此,我想知道是否有可能创建具有通用类型约束的类,然后在方法级别使用附加约束来扩展该通用类型

public class A<T> where T : class
{
    public void Foo(T input) where T : SomeBaseClass // additional constraints for generic type on class level
    {

    }
}

更实际的示例:

public class MessageFlowBuilder<TInput> where TInput : class, new()
{
    private readonly IServiceCollection _services;

    public MessageFlowBuilder(IServiceCollection services)
    {
        _services = services;
    }

    public StandardMessageFlowBuilder<TInput> UseStandardMessageParser() 
        where TInput : StandardMessageBase // additional constraints for generic type on class level (required by parser)
    {
        _services.AddTransient<StandardMessageParser<TInput>>();
        return new StandardMessageFlowBuilder<TInput>();
    }

    public EncryptedMessageFlowBuilder<TInput> UseEncryptedMessageParser() 
        where TInput : EncryptedMessageBase // additional constraints for generic type on class level
    {
        _services.AddTransient<EncryptedMessageParser<TInput>>();
        return new EncryptedMessageFlowBuilder<TInput>();
    }
}

或者是否有可能在方法级别创建另一个泛型,然后将其约束与类级别参数设为同一类型?

public class A<T> where T : class
{
    public void Foo<T2>(T2 input) where T2 : SomeBaseClass // + some T == T2 type equality?
    {

    }
}

3 个答案:

答案 0 :(得分:0)

可以使Foo为通用方法,是的-但是您不能将其约束为与T相同,也不能向现有的类型参数添加约束。 / p>

答案 1 :(得分:-1)

public class A<T> where T : class
{
    public void Foo(T input) where T : SomeBaseClass // additional constraints for generic type on class level
    {

    }
}

否,实例化类时声明了类型T,您不能在方法级别进行更改。

这样做:

new A<SomeBase>();

您已有效地给方法签名:

public void Foo(SomeBase input)

答案 2 :(得分:-1)

您可以尝试这样的方法吗?我什至现在不确定这是否可以编译。该方法也需要自己通用。

public class A<T> where T : class
{
    public void Foo<U>(U input) where U : T, SomeBaseClass, SomeInterface //whatever
    {

    }
}