Generic method with multiple constraints
Asked Answered
M

4

336

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
Mycah answered 26/2, 2009 at 0:55 Comment(0)
C
525

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
Charger answered 26/2, 2009 at 1:5 Comment(2)
Can you have multiple restraints on the same generic like where T : MyClass where T : MyOtherClass ?Rubetta
@Rubetta Sort of. C# does not allow multiple inheritance. However, you can specify some interfaces and other special conditions, as well as the single class. Each requirement is separated by a comma (partially why Martin's attempt was not valid C#: commas in that context already meant something else). So, where T : MyClass, IMyInterface is valid, but where T : MyClass, MyOtherClass is not.Klenk
S
25

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
Soteriology answered 17/5, 2019 at 14:30 Comment(0)
C
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.

Cupola answered 16/2, 2019 at 14:43 Comment(1)
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://mcmap.net/q/76121/-what-exactly-is-an-quot-open-generic-type-quot-in-net-duplicate https://mcmap.net/q/76122/-c-language-generics-open-closed-bound-unbound-constructedHasin
S
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

Skewness answered 8/4, 2021 at 15:55 Comment(2)
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.Dreyfus
Thanks @ToddWest. I have removed the additional comma after MyClassSkewness

© 2022 - 2024 — McMap. All rights reserved.