2013-03-15 31 views
6
MonoBehavior[] list; // This is from Unity3d but think of it as Object, 
        // all classes inherit from it. 

该列表中充满了很多东西,其中一些是来自Alpha类的Alpha,另一些来自其他类。foreach在列表中[C#]

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

我的假设是我的foreach将工作在这种方式下:在列表中找到的foreach阿尔法脚本做一些事情,忽略所有其他组件。

这是一个铸造问题,我想。请帮助我更好地理解cast/polymorphism。

我在执行过程中出现此错误: 不能从源类型转换为目标类型

+0

这么多好的答案,谢谢。我会在一些想法之后选择最好的:) – 2013-03-15 11:42:30

回答

2

这是我会怎么做,我肯定知道这将汇编​​Unity3d。 OfType不是在Unity中,TypeOf只不过是taras.roshko表示使用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没有阿尔法时你不能正确运行。所以你检查一下当前是否是Alpha,然后如果它使用它,但是你喜欢。

0

foreach声明将试图投中的每个对象那里Alpha。如果他们有一个共同的超类,那么可以使用它,否则使用Object类。

2

使用OfType遍历特定类型的元素只有

13

你可以尝试这样的:

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

如果您希望循环只在Alpha类型进行操作,你需要重写为以下:

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

编辑:马滕的答案使用LINQ,这是更简洁,所以我建议一个。

+0

更好的决定是使用'as'运算符 – 2013-03-15 11:34:31

+0

使用'is'关键字有效地与'if(a.GetType == TypeOf(Alpha)'? – Amicable 2013-03-15 11:36:08

+2

'is'不会失败,如果a为null(它将被评估为false),在null上调用'GetType'将导致NullReferenceException,所以'is'方法更好,但更好的是使用'as'运营商。下一步是使用'OfType'LINQ方法) – 2013-03-15 11:38:07

11

您将以错误的方式进行多态:Alpha虽然是派生类型,但并不是MonoBehavior类型列表中的所有其他对象都是。因此,有些会失败foreach正在做的隐式类型转换。 您可以使用“OfType()”的扩展,如果它在你的环境中可用:

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

如果您的列表中包含的基本类型的列表,你只是把每一个元素,并尝试认为它是类型的阿尔法比它是非法的尝试下面

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

假设DoSomething的()是在defind Unity3d