Search code examples
c#asp.netgenericsinheritancegeneric-programming

how to have multiple type for generics in child class


I have a BaseController

public abstract class BaseController<T> : ApiController 
{

    protected APIResponseTO<T> _reponse;

    protected IHttpActionResult CreateResponse(HttpStatusCode httpStatus, T data)
    {
        _reponse = new APIResponseTO<T>()
        {
            HttpStatus = httpStatus,
            Data = data
        };
        return Ok(_reponse);
    }
}

Now I want that any Class which inherits this class can define multiple types for T as

 public class CustomerController : BaseController<T>
 {

    public IHttpActionResult Get()
    {

        var customers = _customerService.GetCustomers();
        //call Parent Class CreateResponse() to create IHttpActionResult object
        //here customers is IEnumerable<Customer>
        return CreateResponse(HttpStatusCode.Created, customers)
    }

    public IHttpActionResult Post([FromBody]Customer customer)
    {
        var custId= _customerService.AddCustomers();
        //call Parent Class CreateResponse() to create IHttpActionResult object
        //here customer is integer(Single Object)
        return CreateResponse(HttpStatusCode.Created, custId)
    }
}

What my requirement is either I can define somehow at the class level

public class CustomerController : BaseController<T> where T : Customer, IEnumerable<Customer>, int
 {
 }

or at Method Level

 public IHttpActionResult Post<T>([FromBody]Customer customer)
  where T : int
    {
        var custId= _customerService.AddCustomers();
        //call Parent Class CreateResponse() to create IHttpActionResult object
        //here customer is integer(Single Object)
        return CreateResponse(HttpStatusCode.Created, custId)
    }

Thanks.


Solution

  • I am not entirely sure I understood exactly what you need, but I think I have an idea.
    I think you should not use a generic class but instead use a generic method:

    public class CustomerController : BaseController
    {
    
        public IHttpActionResult Get()
        {
    
            var customers = new List<object>();
            return CreateResponse<List<object>>(HttpStatusCode.Created, customers);
        }
    
        public IHttpActionResult Post([FromBody]Customer customer)
        {
            int custId = 17;
            return CreateResponse<int>(HttpStatusCode.Created, custId);
        }
    }
    
    public abstract class BaseController : ApiController
    {
    
        protected IHttpActionResult CreateResponse<TData>(HttpStatusCode httpStatus, TData data)
        {
            // Problem here is that BaseController is not a generic class anymore, so you can't store your responses but then again, why would you want to store them in a variable?
            var reponse = new APIResponseTO<TData>()
            {
                HttpStatus = httpStatus,
                Data = data
            };
    
            return Ok(reponse);
        }
    }
    

    Hope this helps.