Reputation: 14097
I've got interface as follows:
public interface IService<T> where T : class
{
Task<IEnumerable<T>> GetAsync<U>(int subscriberId, U request) where U : SearchRequestBase;
}
I'm implementing the following way (CategoriesRequest inherits SearchRequestBase):
public async Task<IEnumerable<CategoriesResponse>> GetAsync<CategoriesRequest>(int subscriberId, CategoriesRequest request)
{
// Implementation
}
But no matter what I do, I get compile errors, the only way to make it work was to put U generic in interface and put constraint there.
Is this recommended way to do it? Or can I declare generic method with constraint next to my method and implement it that way?
My intention is to put generic only as a return type and my input has to contain anything that inherits from SearchRequestBase
.
So this is my base class:
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;
}
And CategoriesRequest
class that now does not yet implement any extra properties (but will).
public class CategoriesRequest : SearchRequestBase
{
}
There are more requests that inherit from SearchRequestBase.
So now there's my IService
interface:
public interface IService<T> where T : class
{
Task<IEnumerable<T>> GetAsync(int subscriberId, SearchRequestBase request);
}
And I implement it in 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;
}
}
However compiler curses at me and gives the following error:
Error CS0535 'CategoryService' does not implement interface member 'IService<CategoriesResponse>.GetAsync(int, SearchRequestBase)'
Upvotes: 1
Views: 1206
Reputation: 119186
Your method signature needs to be:
public async Task<IEnumerable<CategoriesResponse>> GetAsync(
int subscriberId, SearchRequestBase request)
Otherwise you need to add another generic type parameter to the interface. For example:
public interface IService<TRequest, TResponse>
where TRequest : SearchRequestBase
where TResponse : class
{
Task<IEnumerable<TResponse>> GetAsync(int subscriberId, TRequest request);
}
Upvotes: 2