Cypher
Cypher

Reputation: 2707

How do I cast an object to a dynamic type?

All of my objects are composed from a base abstract class called GameObject. All of these objects inherit from one or more interfaces, such as IRenderable, IAnimatable, IMovable, etc.

I also have a list of these objects stored as 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>. 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? Is there another way to accomplish what I want?

Upvotes: 2

Views: 1170

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1503649

Servy has given a better approach, but you can fix your code easily too. Just give the T generic type parameter a constraint:

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.

(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.)

Upvotes: 4

Servy
Servy

Reputation: 203839

LINQ already has a nice handy method for you, 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. 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).

Upvotes: 5

Related Questions