繁体   English   中英

用通用方法实现通用接口

[英]Implementing generic interface with generic method

我的界面如下:

public interface IService<T> where T : class
{
    Task<IEnumerable<T>> GetAsync<U>(int subscriberId, U request) where U : SearchRequestBase;
}

我正在实现以下方式(CategoriesRequest继承SearchRequestBase):

public async Task<IEnumerable<CategoriesResponse>> GetAsync<CategoriesRequest>(int subscriberId, CategoriesRequest request)
{
    // Implementation
}

但是无论我做什么,都会遇到编译错误,使其起作用的唯一方法是在接口中放入U泛型并在其中放置约束。

这是推荐的方法吗? 还是可以在方法旁边声明具有约束的通用方法并以这种方式实现?

我的意图是将泛型仅作为返回类型,并且我的输入必须包含从SearchRequestBase继承的任何内容。

更新

这是我的基类:

public class SearchRequestBase
{
    private const int minimumQueryLength = 3;
    private const int minimumResultsSize = 1;
    private const int maximumResultsSize = 100;
    private const int defaultResultsSize = 5;

    protected SearchRequestBase()
    {
    }

    [Required]
    [MinLength(minimumQueryLength, ErrorMessage = "Query string has to contain at least three characters")]
    public string Query { get; set; }

    [Range(minimumResultsSize, maximumResultsSize, ErrorMessage = "Size must be between 1 and 100")]
    public int Size { get; set; } = defaultResultsSize;
}

现在尚没有实现任何额外属性的CategoriesRequest类(但将会实现)。

public class CategoriesRequest : SearchRequestBase
{
}

还有更多从SearchRequestBase继承的请求。

所以现在有了我的IService接口:

public interface IService<T> where T : class
{
    Task<IEnumerable<T>> GetAsync(int subscriberId, SearchRequestBase request);
}

我在CategoryService实现它:

public class CategoryService : IService<CategoriesResponse>
{
    private readonly IElasticClient _client;

    public CategoryService(IElasticClient client)
    {
        _client = client ?? throw new ArgumentNullException(nameof(client));
    }

    public async Task<IEnumerable<CategoriesResponse>> GetAsync(int subscriberId, CategoriesRequest request)
    {
        var descriptor = new CategoryBuilder().Build(subscriberId, request);

        var index = "categories";

        var response = await _client.SearchAsync<CategoriesResponse>(descriptor.Index(index));

        return response.Documents;
    }
}

但是,编译器对我诅咒并给出以下错误:

Error   CS0535  'CategoryService' does not implement interface member 'IService<CategoriesResponse>.GetAsync(int, SearchRequestBase)'

您的方法签名必须为:

public async Task<IEnumerable<CategoriesResponse>> GetAsync(
    int subscriberId, SearchRequestBase request)

否则,您需要向接口添加另一个通用类型参数。 例如:

public interface IService<TRequest, TResponse>
    where TRequest : SearchRequestBase
    where TResponse : class
{
    Task<IEnumerable<TResponse>> GetAsync(int subscriberId, TRequest request);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM