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