简体   繁体   English

如何将对象转换为动态类型?

[英]How do I cast an object to a dynamic type?

All of my objects are composed from a base abstract class called GameObject . 我的所有对象都是由一个名为GameObject的基本抽象类组成GameObject All of these objects inherit from one or more interfaces, such as IRenderable , IAnimatable , IMovable , etc. 所有这些对象都继承自一个或多个接口,例如IRenderableIAnimatableIMovable等。

I also have a list of these objects stored as List<GameObject> . 我还有一个存储为List<GameObject>的这些对象的List<GameObject> I'm trying to write a dynamic method that will return to me all of the objects that has inherited from a specific interface, like so: 我正在尝试编写一个动态方法,它将返回从特定接口继承的所有对象,如下所示:

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

At first, I tried just returning a new list of game objects where each object's type matches the dynamic type, then casting the List<GameObject> to List<T> . 首先,我尝试返回一个新的游戏对象列表,其中每个对象的类型与动态类型匹配,然后将List<GameObject>List<T> The compiler error I received said that I could not convert those types. 我收到的编译错误说我无法转换这些类型。

So my second attempt involved casting each object individually, as shown below. 因此,我的第二次尝试涉及单独投射每个对象,如下所示。

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;
}

However, this throws the same type of error; 但是,这会引发相同类型的错误; cannot convert type GameObject to T. Am I missing something? 无法将GameObject类型转换为T.我错过了什么? Is there another way to accomplish what I want? 还有另一种方法可以实现我想要的吗?

LINQ already has a nice handy method for you, OfType() . LINQ已经为你提供了一个非常方便的方法, OfType()

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

OfType will return a sequence with all of the items from the input sequence that can be cast to the type you specified. OfType将返回一个序列,其中包含输入序列中可以强制转换为您指定类型的所有项。 Additionally there is the Cast<T>() operator which just tried to cast everything and will throw an exception if an item can't be cast (which doesn't appear to be what you want here). 另外还有Cast<T>()运算符,它只是试图Cast<T>()转换所有内容,并且如果某个项目无法转换将抛出异常(这似乎不是您想要的)。

Servy has given a better approach, but you can fix your code easily too. Servy提供了更好的方法,但您也可以轻松修复代码。 Just give the T generic type parameter a constraint: 只需给T泛型类型参数一个约束:

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

Another (nastier) alternative is to add an extra cast: 另一个(更糟糕的)替代方案是添加一个额外的演员:

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

Conversions to a generic type parameter are a bit messy. 转换为泛型类型参数有点乱。 See Eric Lippert's blog post for more details. 有关详细信息,请参阅Eric Lippert的博客文章

(I'd definitely use Servy's approach - there's no point in reinventing the wheel - I just wanted to explain how to fix your code in similar situations.) (我肯定会使用Servy的方法 - 重新发明轮子没有意义 - 我只想解释如何在类似情况下修复代码。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM