Can I dictate that a C# type parameter must only be an interface type?
I would like to implement a generic C# class which looks roughly as follows:
abstract class Foobar<T> : AbstractBase, T
{ ... }
This fails because C# will only allow types after the base class to be interfaces, so next I try this:
abstract class Foobar<T> : AbstractBase, T where T : interface
{ ... }
But then I find that C# does not allow this form of type constraint. Onl开发者_Python百科y where T : struct
and where T : class
are allowed.
How can I dictate that a type parameter must only be an interface type?
Basically, you can't.
You can make a contstraint to a specific interface, but not a general one for all interfaces. So you can constrain to IEnumerable for example, but not any interface.
What do you need this for anyway?
The real problem with that code is that you are inheriting from a type parameter.
Trying to compile
abstract class Foobar<T> : T { ... }
will still fail with: error CS0689: Cannot derive from 'T' because it is a type parameter.
I think that this would be perfectly reasonable at least in the case of abstract classes, and I wanted this feature too, but the c# compiler just wont let you do that.
I believe that you misunderstand the meaning of where T : struct
and where T : class
.
A generic type constraint like this means that T
must be a value type or a reference type respectively.
However, the purpose of an interface is to define a contract, which is a totally different concept as compared to value type vs. reference type semantics.
Therefore a restriction like where T : interface
would make no sense.
If you want to know more, I would suggest you to read the C# Programming Guide on type constraints:
Constraints on Type Parameters (C# Programming Guide)
You can't in simple words.
This fails because C# will only allow types after the base class to be interfaces
This constraint is due to the lack of multiple inheritance in C#. Multiple inheritance can be approximated by the use of interfaces because the overriding methods are explicit. The same way a class can only extend one other class, but can implement multiple interfaces. The trick here is that the implementing class MUST define the body for a method, so that the implementation is specific on which method is called.
Using a where to limit T can be applied to one class, or several interfaces. You can not limit the range to several classes.
精彩评论