Reputation: 2707
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
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
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