Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic method returning generic type

I am using a restclient that accepts a type, which is later converted to the correct IRestResponse.

IRestResponse<MyClassA> response = client.Execute<MyClassA>();

Since MyClassA can also be MyClassB or MyClassC I thought about making a generic method which could handle this. However without any luck. This is my attempt:

public interface IRestClient{ IRestResponse response = PerformExecuteClient()

private RestResponse<T> PerformExecuteClient<T>() {
    return client.Execute<T>();
}

The compiler tells me that client.Execute<T> does not accept abstract types. Which makes sense, but I have no idea how else to make this method. Is it possible what I am trying to achieve here?

Additional information based on some comments. As Brains Mains suggested, the method is not accepting the abstract type here.

public interface IRestClient{
    IRestResponse<T> Execute<T>(IRestRequest request) where T : new();
}
like image 631
Jorn Theunissen Avatar asked Mar 12 '23 09:03

Jorn Theunissen


2 Answers

The signature is:

IRestResponse<T> Execute<T>(IRestRequest request) where T : new();

The generic constraint of new does not allow abstract classes. Instead you can:

  1. Have an interface for your classes and have a generic constraint on that.
  2. Change your MyClassA to not being abstract
  3. Remove the constraint

Me personally - I'd say the interface option - but this is opinion based :)

In any case for the PerformExecuteClient<T> it must follow at least the generic constraints of the Execute<T> which it executes.

like image 127
Gilad Green Avatar answered Mar 24 '23 10:03

Gilad Green


Did you try this:

private RestResponse<T> PerformExecuteClient<T>() where T : new()
{
    return client.Execute<T>();
}

As everyone pointed out here, you have to follow the interface's generic constraint to make this work. If you don't, you do not respect the interface contract by passing an unexpected type.

Also where T : new() means that you can instantiate T like this new T(). But by definition, an abstract class can't be instantiate, that is why you get this error.

like image 36
romain-aga Avatar answered Mar 24 '23 12:03

romain-aga