If I have a generic method like this one:
static void Foo<T>() where T : class
{
}
I could call it by specifying an interface type, for example ICollection<int>
Foo<ICollection<int>>();
Now assume I have a struct that implements ICollection<int>
:
struct Bar : ICollection<int>
I can't specify it explicitly as the type argument, but if I have a variable of type ICollection<int>
that has the underlying type Bar
, and change my generic method to take an argument of type T
, I can do:
static void Foo<T>(T arg) where T : class
{
}
ICollection<int> bar = new Bar();
Foo <ICollection<int>>(bar);
As you can see it completely ignores the generic constraint. So my question is why specifying an interface as a type argument is allowed when we have a class
constraint?
The "class" constraint is really a "reference type" constraint - it doesn't specifically mean classes. (It works with delegate types too.) From the MSDN page on generic type constraints:
The type argument must be a reference type; this applies also to any class, interface, delegate, or array type.
Now for your example:
As you can see it completely avoids the generic constraint.
No it doesn't. It uses ICollection<int>
as the type argument, and that is a reference type. Note tha the value you're passing into the method is a reference, due to boxing.
See more on this question at Stackoverflow