2

我所有的对象都由一个名为GameObject. 所有这些对象都继承自一个或多个接口,例如IRenderableIAnimatableIMovable等。

我还有一个存储为List<GameObject>. 我正在尝试编写一个动态方法,它将返回给我从特定接口继承的所有对象,如下所示:

List<IRenderable> renderableObjects = ObjectManager.GetAll<IRenderable>();

起初,我尝试只返回一个新的游戏对象列表,其中每个对象的类型都与动态类型匹配,然后将其转换List<GameObject>List<T>. 我收到的编译器错误说我无法转换这些类型。

所以我的第二次尝试涉及单独投射每个对象,如下所示。

public List<T> GetAll<T>() {
    List<T> list = new List<T>();

    foreach( GameObject obj in this.gameObjects )
        if( obj is T )
            list.Add( (T)obj );

     return list;
}

但是,这会引发相同类型的错误;无法将 GameObject 类型转换为 T。我错过了什么吗?还有另一种方法来完成我想要的吗?

4

2 回答 2

5

LINQ 已经为您提供了一个非常方便的方法,OfType().

List<GameObject> list = ...;
var movableObjects = list.OfType<IMovable>();

OfType将返回一个序列,其中包含输入序列中的所有项目,这些项目可以转换为您指定的类型。此外,还有一个Cast<T>()操作员只是尝试投射所有内容,如果无法投射项目(这似乎不是您想要的),则会抛出异常。

于 2012-11-08T21:12:04.900 回答
4

Servy 提供了更好的方法,但您也可以轻松地修复代码。只需给T泛型类型参数一个约束:

public List<T> GetAll<T>() where T : GameObject {

另一个(更糟糕的)替代方案是添加额外的演员表:

list.Add((T)(object)obj);

到泛型类型参数的转换有点混乱。有关详细信息,请参阅Eric Lippert 的博客文章

(我肯定会使用 Servy 的方法——重新发明轮子没有意义——我只是想解释如何在类似情况下修复你的代码。)

于 2012-11-08T21:12:48.303 回答