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

清单里有很多东西,有些是 Alpha,来自 Alpha 类,还有一些来自其他类。

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

我假设我的 foreach 会以这种方式工作:在列表中找到的 Foreach Alpha 脚本做某事,忽略所有其他组件。

我认为这是一个选角问题。请帮助我更好地理解铸造/多态性。

我在执行期间收到此错误: 无法从源类型转换为目标类型

4

7 回答 7

15

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

foreach(Alpha a in list.OfType<Alpha>())
于 2013-03-15T11:34:00.740 回答
13

您可以尝试以下方法:

foreach(Alpha a in list.Where(x => x is Alpha)) // Alpha is a script. 
  a.doSomething();
于 2013-03-15T11:33:03.713 回答
2

使用OfType仅迭代指定类型的元素

于 2013-03-15T11:32:52.330 回答
2

如果您希望循环仅对Alpha类型进行操作,则需要重写如下:

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

编辑:Maarten 的回答使用更简洁的 LINQ,所以我推荐那个。

于 2013-03-15T11:33:48.210 回答
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,因此您无法正确运行它。因此,您检查 current 是否为 Alpha,然后检查是否可以随意使用它。

于 2013-03-16T04:51:57.480 回答
0

您的foreach语句将尝试将其中的每个对象转换为Alpha. 如果他们有一个共同的超类,您可以使用它,否则使用Object该类。

于 2013-03-15T11:24:18.827 回答
0

如果您的列表包含基本类型列表并且您只是获取每个元素并尝试认为它是 Alpha 类型而不是非法尝试下面

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

假设在 Unity3d 中定义了 doSomething()

于 2013-03-15T11:36:57.527 回答