2

So I have two interfaces:

public interface ISomething
{
    public int A();
}


public interface ISomethingElse
{
    public int B();
}

And an object that implements both:

public class MyObject : ISomething, ISomethingElse
{      
}

Now I have this running code:

...
List<MyObject> objects = myObjectManager.SelectAll(); // now have say 10 MyObject

MyUtilityClass myUtilityClass = new MyUtilityClass();
MyOtherUtilityClass myOtherUtilityClass = new MyOtherUtilityClass();
myUtilityClass.MySpecialMethod(objects);                  // <- compile failure
myOtherUtilityClass.MySpecialMethod(objects);             // <- another failure
...

If I want to call A or B on all of them, how can I write code like this:

public class MyUtilityClass
{
    public void MySpecialMethod(List<ISomething> objects) // <- the problem
    {
        foreach (ISomething o in objects)
            o.A();   
    }
}

public class MyOtherUtilityClass
{
    public void MySpecialMethod(List<ISomethingElse> objects) // <- the problem
    {
        foreach (ISomethingElse o in objects)
            o.B();   
    }
}

How can I cleanly call MyUtilityClass.MySpecialMethod() on my List<MyObject> objects? Is it possible without all typecasting? The parameters of MyUtilityClass.MySpecialMethod() appear to be the issue (I want to define the parameter as a List of objects that implement ISomething).

2
  • are you getting a compile error? What is it? edit: Or is the problem that you do not want to have to do the cast in MySpecialMethod? Commented May 3, 2011 at 22:05
  • It was indeed related to avoiding the cast. Commented May 3, 2011 at 23:12

4 Answers 4

5

You can use IEnumerable<> interface instead of List<>. IEnumerable<> is covariant.

Sign up to request clarification or add additional context in comments.

1 Comment

You can read more about covariance/contravariance here
4

List does not support covariance.

You may change it to IEnumerable<ISomething> and pass a List<MyObject>.

Comments

4

Personally, I would use the following signature as IEnumerable<T> is covariant:

public void MySpecialMethod(this IEnumerable<ISomething> objects) // <- the problem
{
    foreach (ISomething o in objects)
        o.A();   
}

Calling it:

objects.MySpecialMethod();

Comments

1

Shouldn't

public void MySpecialMethod(List<MyObject> objects)
{
    foreach (ISomethingElse o in objects)
        o.B();   
}

work?

1 Comment

Yes but I want to accept any object that implements the interface not a concrete object type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.