Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why specifying a generic argument as interface is not an error with a class constraint?

Tags:

c#

generics

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?

like image 937
Selman Genç Avatar asked Nov 27 '14 23:11

Selman Genç


People also ask

What does the generic constraint of type interface do?

Interface Type Constraint You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter.

What is the purpose of the class constraint on a type parameter?

Object, you'll apply constraints to the type parameter. For example, the base class constraint tells the compiler that only objects of this type or derived from this type will be used as type arguments. Once the compiler has this guarantee, it can allow methods of that type to be called in the generic class.

What does the generic constraint of type interface do in C#?

Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type. They declare capabilities that the type argument must have, and must be placed after any declared base class or implemented interfaces.

Can a generic implement an interface?

Only generic classes can implement generic interfaces. Normal classes can't implement generic interfaces.


1 Answers

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.

like image 155
Jon Skeet Avatar answered Sep 21 '22 02:09

Jon Skeet