7
interface IVehicle 
{
    void DoSth();
}

class VW : IVehicle
{
    public virtual void DoSth() { ... }
}

class Golf : VW { }

class Lupo : VW
{
    public override void DoSth()
    {
        base.DoSth();
        ...
    }  
}

in my code i have:

List<VW> myCars = new List<VW>();
myCars.Add(new Golf());
myCars.Add(new Lupo());

now i want to evaluate if i have a list of vehicles. something like:

if(myCars is List<IVehicle>)
{
    foreach(IVehicle v in myCars)
        v.DoSth();
}

how can i do this? the is-operator on the generic list does not work. is there another way?

3
  • Checking to see whether a list of VW objects is a list of IVehicle objects seems silly, since VW inherits from IVehicle amd you are therefore writing if(true). Besides, since VW inherits from IVehicle and myCars is a List<VW>, foreach (IVehicle v in myCars) will simply work. Commented Feb 19, 2012 at 20:10
  • @Steven: a list of VW is emphatically not a list of IVehicle, because you can add a Ford to a list of IVehicle, but not to a list of VW. Commented Feb 20, 2012 at 0:49
  • Yes, but you are simply iterating that list, which is safe. Commented Feb 20, 2012 at 16:03

3 Answers 3

11

Even with 4.0 variance rules, a list-of-VW is not ever a list-of-IVehicle, even if a VW is an IVehicle. That isn't how variance works.

However, in 4.0, you could use:

var vehicles = myCars as IEnumerable<IVehicle>;
if(vehicles != null) {
     foreach(var vehicle in vehicles) {...}
}

Since IEnumerable<out T> exhibits covariance.

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

3 Comments

And if(myCars is IEnumerable<IVehicle>) will work as well in .NET 4.0.
Just for completeness, I should note that arrays can be covariant (for reference-types), but in a can-error-at-runtime way.
@Steven indeed; I just hate doing the test twice ;p
2

In .net 4 it is posible using generic parameter variance. Read more about it here

Comments

0

You could do this:

if (typeof(IVehicle).IsAssignableFrom(myCars.GetType().GetGenericArguments[0]))
    foreach (IVehicle v in myCars)
        //...

This assumes that you know myCars is a generic type. If you don't know that for sure, you would need to do an additional check or two first.

However, since you aren't using any member of list other than GetEnumerator, you can do this:

if (myCars is IEnumerable<IVehicle>) //...

Comments

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.