views:

341

answers:

3

Is it possible to define a function that takes in a parameter that must implement two interfaces?

(The two interfaces are ones I just remembered off the top of my head; not the ones I want to use)

private void DoSomthing(IComparable, ICollection input)
{

}
+5  A: 

You can inherit another interface from those two interfaces and make your parameter implement that interface.

Steve Willcock
only works if you can change ALL the classes that implements both interfaces to implement the new interface.
Ian Ringrose
Well, not ALL of them necessarily. Just the ones you need to use as a parameter for that method.
Steve Willcock
+31  A: 

You can:

1) Define an interface that inherits both required interfaces:

public interface ICombinedInterface : IComparable, ICollection {... }

private void DoSomething(ICombinedInterface input) {... }

2) Use generics:

private void DoSomething<T>(T input)
    where T : IComparable, ICollection
{...}

HTH, Kent

Kent Boogaart
in VB.Net: Private Sub DoSomthing(Of T As {IComparable, ICollection})(ByVal input As T) ... End Sub
Pondidum
Is there a gain using one of these solutions over having two seperate parameters? Intuitively it seems like it would be useful, but I'm struggling to think of a concrete example.
CurtainDog
I cannot think of one at the moment, but I did want to do this few days ago. and having one parameter looks better than calling DoSomthing(testData,testData) and thus passing the same instance in twice.
Pondidum
+1 for the generic route.
Peter Lillevold
1) only works if you can change ALL the classes that implements both interfaces to implement the new interface. 2) I like the generic route
Ian Ringrose
+1  A: 

Well, yes, and no.

You can, as Steve has suggested, create another, third, interface which descends from the two you want, and use that for the parameter type.

However, this will also make it a requirement that the class being used implements that third interface as well.

In other words, this won't work:

public interface I1 { }
public interface I2 { }
public class C : I1, I2 { }

public interface I3 : I1, I2 { }
public class YourClass
{
    public void Test(I3 i) { }
}

...
YourClass yc = new YourClass();
C c = new C();
yc.Test(c); // won't work, C does not implement I3

However, you can trick the compiler into what you want by way of generics.

public class YourClass
{
    public void Test<T>(T i) where T: I1, I2 { }
}

Now it will work. I'm still not 100% sure that won't give you other issues though, I'd have to think about it.

Lasse V. Karlsen