6

Here is my generic method code:

  public static IT Activate<IT>(string path)
  {
        //some code here....
  }

I'd want to set that generic IT must be only an interface.

Is this possible?

DreadAngel
  • 772
  • 11
  • 30
  • Great answers below, but why do you want that restriction? – n8wrl Oct 04 '12 at 15:29
  • As far as I know it's not possible. You can however set a constraint on an interface-name. Not tested but I think that when you use that interface as base for all your interfaces, it could work. Not sure if it's worth the effort. – Koen Oct 04 '12 at 15:29
  • 1
    Check [`Constraint on Type Parameters`](http://msdn.microsoft.com/en-us/library/d5x73970(v=vs.80).aspx), you can't do this, but perhaps you already know which interface you want to use, in this case you can use `where T : ` – Zbigniew Oct 04 '12 at 15:31
  • I need that restriction because that method finds if the assembly located on "path" contains any class that implements interface IT. – DreadAngel Oct 04 '12 at 19:31

4 Answers4

7

No, there's no such constraint in C#, or in .NET generics in general. You'd have to check at execution time.

if (!typeof(IT).IsInterface)
{
    // Presumably throw an exception
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
3

No, you can't constraint IT to any interface type and interface alone. The closest you have is the class constraint and it applies to any class, interface, delegate, or array type. - http://msdn.microsoft.com/en-us/library/d5x73970.aspx

manojlds
  • 290,304
  • 63
  • 469
  • 417
1

The closest thing I can think of would be a runtime check in the static contructor. Like this:

static MyClass<IT>()
{
    if(!typeof(IT).IsInterface)
    {
        throw new WhateverException("Oi, only use interfaces.");
    }
}

Using the static contructor hopefully means it will fail fast, so the developer would discover the mistake sooner.

Also the check will only run once of each type of IT, not every method call. So won't get a performance hit.

Buh Buh
  • 7,443
  • 1
  • 34
  • 61
0

I've just made a quick test about the use of a base-interface. It's possible, but as I said, not sure if it's worth the effort or even if it's good practice.

public interface IBaseInterface
{
}

public interface IInterface1 : IBaseInterface
{
        //some code here.... 
}

public interface IInterface2
{
        //some code here.... 
}

public class Class1
{
    public void Test()
    {
        Activate<IInterface1>("myPath");
        //Activate<IInterface2>("myPath"); ==> doesn't compile
    }

    public static IT Activate<IT>(string path) where IT : IBaseInterface
    {
        //some code here.... 
    }
}
Koen
  • 2,501
  • 1
  • 32
  • 43
  • Hi Koen, That won't force IT to be an interface. IT could still be a class which derives from IBaseInterface. But still, maybe better than nothing. At least would it force people to stop and think before they could use the method. – Buh Buh Oct 04 '12 at 16:26
  • @BuhBuh Correct. I've overlooked that possibility. But it would be pretty useless to derive from an empty interface and like you said would enforce people to think before using it. – Koen Oct 04 '12 at 16:54
  • So the interface-check at execution time looks to be the only solution here. I'm going to leave this answer here, so others won't make the same mistake as I did. – Koen Oct 04 '12 at 16:56