is-оператор в общем списке - PullRequest
7 голосов
/ 20 февраля 2012
interface IVehicle 
{
    void DoSth();
}

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

class Golf : VW { }

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

в моем коде у меня есть:

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

Теперь я хочу оценить, есть ли у меня список транспортных средств.что-то вроде:

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

как я могу это сделать?Оператор is в общем списке не работает.есть ли другой способ?

Ответы [ 3 ]

11 голосов
/ 20 февраля 2012

Даже с правилами дисперсии 4.0, список VW никогда не является списком автомобилей, даже если VW является автомобилем. Это не то, как работает дисперсия.

Однако в 4.0 вы могли бы использовать:

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

Так как IEnumerable<out T> проявляет ковариацию.

2 голосов
/ 20 февраля 2012

В .net 4 это возможно с использованием общей дисперсии параметров.Подробнее об этом здесь

0 голосов
/ 20 февраля 2012

Вы можете сделать это:

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

Предполагается, что вы знаете, что myCars является универсальным типом. Если вы точно этого не знаете, сначала вам нужно будет сделать еще одну или две дополнительные проверки.

Однако, поскольку вы не используете какой-либо элемент списка, кроме GetEnumerator, вы можете сделать это:

if (myCars is IEnumerable<IVehicle>) //...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...