foreach в списке [C#]

MonoBehavior[] list; // This is from Unity3d but think of it as Object, 
                     // all classes inherit from it.

список заполнен множеством вещей, некоторые из них Альфа, из класса Альфа, а другие из других классов.

foreach(Alpha a in list) // Alpha is a script. 
  a.doSomething();

Я предполагал, что мой foreach будет работать таким образом: Альфа-скрипт Foreach, найденный в списке, что-то делает, игнорирует все остальные компоненты.

это проблема кастинга, я думаю. Пожалуйста, помогите мне лучше понять литье/полиморфизм.

Я получаю эту ошибку во время выполнения: не удается бросить из источника тип к типу назначения

7 ответов


вот как я бы это сделал, и я точно знаю, что он будет компилироваться в Unity3d. Кстати, OfType не находится в единстве, TypeOf-это as Тарас.Рошко!--5--> сказал, используя is лучше.

MonoBehavior[] list;

foreach(MonoBehavior current in list) // Search the whole list for MonoBehaviors.
    if (current  is Alpha)            // Check if current is an Alpha type.
        current.doSomething();        // current is a valid Alpha type script.

на foreach попытается преобразовать все элементы в списке, и так как Alpha является MonoBehavior, но MonoBehavior не Альфа, вы не можете запустить его правильно. Таким образом, вы проверяете, является ли ток альфой, а затем, если он используется, как вам нравится.


вы можете попробовать что-то вроде:

foreach(Alpha a in list.Where(x => x is Alpha)) // Alpha is a script. 
  a.doSomething();

вы идете по полиморфизму неправильным путем: хотя Alpha является производным типом,не все другие объекты в вашем списке типа MonoBehavior. Следовательно, некоторые из них потерпят неудачу в неявном приведении типа, которое делает foreach. Вы можете использовать расширение "OfType ()", если оно доступно в вашей среде:

foreach(Alpha a in list.OfType<Alpha>())

использовать метод oftype перебирать только элементы указанного типа


Если вы хотите, чтобы цикл работал только на Alpha типы, нужно переписать следующим образом:

foreach (var item in list)
{
  if (item is Alpha)
  {
    ((Alpha) item).doSomething();
  }
}

edit: ответ Мартена использует LINQ, который является более кратким, поэтому я бы рекомендовал этот.


код foreach оператор попытается бросить каждый объект туда, чтобы Alpha. Если у них есть общий суперкласс, вы можете использовать его, иначе используйте Object класса.


Если ваш список содержит список базового типа, и вы просто берете каждый элемент и пытаетесь думать, что он имеет тип Alpha, чем это незаконно, попробуйте ниже

foreach(Unity3d a in list) // Alpha is a script. 
     a.doSomething();

предполагая, что doSomething () defind в Unity3d