Why is specifying a general argument as an interface not a class restriction error?

If I have a general method like this:

static void Foo<T>() where T : class { } 

I could call it by specifying the type of interface, for example ICollection<int>

 Foo<ICollection<int>>(); 

Now suppose I have a structure that implements ICollection<int> :

 struct Bar : ICollection<int> 

I cannot specify it explicitly as a type argument, but if I have a variable of type ICollection<int> that has a base type of Bar and changes its general method to accept 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 general constraint. So my question is why is specifying an interface as a type argument allowed if we have a class constraint?

+6
source share
2 answers

A class constraint is really a "reference type" - it does not mean, in particular, classes. (It also works with delegate types.) From an MSDN page with general type restrictions :

The type argument must be a reference type; this also applies to any class, interface, delegation, or array type.

Now for your example:

As you can see, he completely avoids the general restriction.

No no. It uses ICollection<int> as a type argument, and it is a reference type. Note that the value you pass to the method is a box reference.

+7
source

From the documentation

where T: class => The type argument must be a reference type; this also applies to any class, interface, delegation, or array type.

Type restrictions

int is the type of value, but ICollection<int> is not.

+1
source

Source: https://habr.com/ru/post/978812/


All Articles