Alexander
Alexander

Reputation: 4219

Having a list of a certain class that implements an interface

I have a class, Component, and an interface, IInventoriable. I need to have a list of objects that are only of class Component, and implement the IInventoriable interface, similar to this answer in Java.

Example psuedocode -

public List<Component implements IInventoriable> Inventory;

How might I accomplish something like this / is it even possible in C#?

Would a better solution be to subclass Component? For some context, I'm using an entity-component system found in many game engines like Unity.

Upvotes: 0

Views: 97

Answers (2)

Doc
Doc

Reputation: 281

I don't think this is possible without type params. With type params you can do something like

int Method<T>(List<T> inventory) where T : Component, IInventoriable { ... }

you could give your class a type param with that constraint, which will then always be Component implements IInventoriable, but then you'd have to figure out how to set it, which probably wouldn't be possible without another type param, then another ...


However there are some other options:

  • Separate the IInventoriable functionality from the component. For instance, make Component objects have an instance variable inventoryItem, which is an IInventoriable. If the component's aren't inventoriable, than their inventoryItem will be null. Then make a list of these inventoryItems instead of a list of components
  • Make Component into an interface, and have the IInventoriable interface implement it
  • If you're not going to use the Component functionality, just have a List<IInventoriable>
  • If you absolutely know that all IInventoriable objects have to be Components, do a runtime check; have a List<IInventoriable> and cast to a component when needed

Upvotes: 2

Nkosi
Nkosi

Reputation: 247153

You could try linq OfType when populating the list. list can be List<Component> but when populating it or filtering the list you can use linq extension Inventory.OfType<IInventoriable>() which will only return the Component derived objects that also implement IInventoriable

Or

create your own List derived generic class with those constraints

public class InventoriableComponentList<T> : System.Collections.Generic.List<T>
    where T : Component, IInventoriable {

    public InventoriableComponentList()
        : base {

    }

    public InventoriableComponentList(IEnumerable<T> collection)
        : base(collection) {

    }
}

Upvotes: 3

Related Questions