I'm making an HTTP API client class.
I want a Perform()
method which takes a request object and returns an obejct that is expected from the API.
So a PostRequest
object will describe how to get a Post
.
Ultimately what I'm trying to do is the following:
Post post = client.Perform<PostRequest>(x => x.Id = 1);
I'm trying to infer the return type based on the Request
generic.
My PostRequest class looks like this:
internal class PostRequest : Request<Post>
{
internal int Id { get; set; }
}
The problem is I can't infer that the purpose of the PostRequest
is to return a Post
.
That is, I can only get this to work when my method looks like this, where Post
is included in the generic method.
public TModel Perform<TRequest, TModel>(Action<TRequest> action) where TRequest : Request<TModel> where TModel : class
But I was hoping to simplify the method like this:
public TModel Perform<TRequest>(Action<TRequest> action) where TRequest : Request<TModel>
But I can't tell C# how to derive what a TModel
is.
Is there any way to achieve what I want? Or will I always have to tell the generic method what return I'm expecting? (even though this is included in the PostRequest
)
I'm open to suggestions of a better approach.
Best Answer
First of all, you can not expect to get class which pass into Request as T type by using
PostRequest
because it could be implements more than one interface.Beyond, you can use
Request<T>
instead of concrete class. It is totally same for this logic.And, I think you try to predicate(not assign) by doing
(x => x.Id = 1)
. If so, I assume this code like(x => x.Id == 1)
. It means you are trying to determine prediction by passing parameter to method.If I get correctly, you have two option to achieve this by using System.Linq.Expressions:
1. As method parameter:
As you see, you don't need
PostRequest
orPhotoRequest
classes for this usage.2. Store in class properties
And you can call
Perform
like :