我的界面如下:
public interface IService<T> where T : class
{
Task<IEnumerable<T>> GetAsync<U>(int subscriberId, U request) where U : SearchRequestBase;
}
我正在实现以下方式(CategoriesRequest继承SearchSearchBase):
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)'
答案 0 :(得分:2)
您的方法签名必须为:
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);
}