328

I have a generic method which has two generic parameters. I tried to compile the code below but it doesn't work. Is it a .NET limitation? Is it possible to have multiple constraints for different parameter?

public TResponse Call<TResponse, TRequest>(TRequest request)
  where TRequest : MyClass, TResponse : MyOtherClass
ccalboni
  • 12,120
  • 5
  • 30
  • 38
Martin
  • 39,309
  • 62
  • 192
  • 278

4 Answers4

512

It is possible to do this, you've just got the syntax slightly wrong. You need a where for each constraint rather than separating them with a comma:

public TResponse Call<TResponse, TRequest>(TRequest request)
    where TRequest : MyClass
    where TResponse : MyOtherClass
Pang
  • 9,564
  • 146
  • 81
  • 122
LukeH
  • 263,068
  • 57
  • 365
  • 409
  • 7
    Can you have multiple restraints on the same generic like `where T : MyClass where T : MyOtherClass` ? – WDUK Apr 23 '22 at 08:18
24

In addition to the main answer by @LukeH with another usage, we can use multiple interfaces instead of class. (One class and n count interfaces) like this

public TResponse Call<TResponse, TRequest>(TRequest request)
  where TRequest : MyClass, IMyOtherClass, IMyAnotherClass

or

public TResponse Call<TResponse, TRequest>(TRequest request)
  where TRequest : IMyClass,IMyOtherClass
Hamit YILDIRIM
  • 4,224
  • 1
  • 32
  • 35
12

In addition to the main answer by @LukeH, I have issue with dependency injection, and it took me some time to fix this. It is worth to share, for those who face the same issue:

public interface IBaseSupervisor<TEntity, TViewModel> 
    where TEntity : class
    where TViewModel : class

It is solved this way. in containers/services the key is typeof and the comma (,)

services.AddScoped(typeof(IBaseSupervisor<,>), typeof(BaseSupervisor<,>));

This was mentioned in this answer.

Maytham Fahmi
  • 31,138
  • 14
  • 118
  • 137
  • 2
    This answer is not related to type constraints at all. It is about unbound generic types and how to spell them out in C#. https://stackoverflow.com/a/2173115/2157640 https://stackoverflow.com/a/6607299/2157640 – Palec Mar 28 '19 at 12:50
6

Each constraint need to be on own line and if there are more of them for single generic parameter then they need to separated by comma.

public TResponse Call<TResponse, TRequest>(TRequest request)
    where TRequest : MyClass 
    where TResponse : MyOtherClass, IOtherClass

Edited as per comment

mybrave
  • 1,662
  • 3
  • 20
  • 37
  • This answer is incorrect, both in the comma following MyClass (see most upvoted answer) and the claim constraints need to be on separate lines. I'd fix it, but the edit queue is full. – Todd West Sep 22 '21 at 18:19
  • Thanks @ToddWest. I have removed the additional comma after `MyClass` – mybrave Sep 23 '21 at 09:45