views:

1402

answers:

5

Is there a way to get the following function declaration?

public bool Foo<T>() where T : interface;

ie. where T is an interface type (similar to where T : class, and struct).

Currently I've settled for:

public bool Foo<T>() where T : IBase;

Where IBase is defined as an empty interface that is inherited by all my custom interfaces... Not ideal, but it should work... Why can't you define that a generic type must be an interface?

For what it's worth, I want this because Foo is doing reflection where it needs an interface type... I could pass it in as a normal parameter and do the necessary checking in the function itself, but this seemed alot more typesafe (and I suppose a little more performant, since all the checks are done at compiletime).

+1  A: 

No, actually, if you are thinking class and struct mean classes and structs, you're wrong. class means any reference type (e.g. includes interfaces too) and struct means any value type (e.g. struct, enum).

Mehrdad Afshari
Isn't that the definition of the difference between a class and a struct though: that every class is a reference type (and vice versa) and ditto for stuct/value types
Matthew Scharley
Matthew: There are more to value types than C# structs. Enums, for instance are value types and match `where T : struct` constraint.
Mehrdad Afshari
+1  A: 

You cannot do this in any released version of C#, nor in the upcoming C# 4.0. It's not a C# limitation, either - there's no "interface" constraint in the CLR itself.

Pavel Minaev
A: 

What would be the benefit of having a constraint of this type? There is nothing you could do that you couldn't do by using the "class" restraint.

Philippe Leybaert
He explains it - he needs T to be an interface because he'll be using typeof(T) and passing it to something that expects an interface.
Pavel Minaev
If it existed, WebChannelFactory would use it since it requires an interface for its TChannel generic type parameter
James Manning
+5  A: 

The closest you can do (except for your base-interface approach) is "where T : class", meaning reference-type. There is no syntax to mean "any interface".

This ("where T : class") is used, for example, in WCF to limit clients to service contracts (interfaces).

Marc Gravell
A: 

Use an abstract class instead. So, you would have something like:

public bool Foo() where T : CBase;

Eddie