Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a list of something that implements abstract class and interface (C#)?

Tags:

c#

generics

Let's say i have list of Tanks,Airplanes and many other things that the to common thing they implement is IHaveLocation which is and abstract class and IHaveColor which is an interface.

I want to make a list of them because i need to query the list on the basis of this two interfaces.

How do i do it ?

  • I can make a list of objects and then write (obj as IHaveLocation) and use his methods, and (obj as IHaveColor) and use his methods. but this is very very ugly !
  • I can make a list of IhaveLocation and then i need to do only one as (obj as IHaveColor). But it's also terrible
  • I can create a new abstract class then inherits from both, but i'm trying to avoid it.

is there some trick to this ?

I Want to make something like List<IHaveLocation and IHaveColor>

like image 706
OopsUser Avatar asked Jan 14 '23 19:01

OopsUser


2 Answers

You can wrap this in a generic class with constraints on both types:

public class YourClass<T> where T : IHaveLocation, IHaveColor
{
    List<T> items = new List<T>;

    public void Add(T item)
    {
        items.Add(item);
    }
    // ...
}

Methods within this class can then use both interfaces as needed, as the type is guaranteed to implement them.

like image 124
Reed Copsey Avatar answered Jan 31 '23 00:01

Reed Copsey


As I mentioned in the comments of Reed's answer, you could use generic methods to allow you to add both Tank's and Airplane's. Something like this:

class TwoTypesList<T1, T2>
{
    List<Tuple<T1, T2>> m_list = new List<Tuple<T1,T2>>();

    public void Add<ConcreteT>(ConcreteT item) where ConcreteT : T1, T2
    {
        m_list.Add(Tuple.Create<T1, T2>(item, item));
    }
}

Then the usage would be:

        TwoTypesList<IHaveColor, IHaveLocation> list = new TwoTypesList<IHaveColor, IHaveLocation>();
        Airplane a = new Airplane();
        Tank t = new Tank();
        list.Add(a);
        list.Add(t);

The downside, of course, is that you're storing the object twice. If you don't like that, then of course you could change the internal storage of the list to be an object or only one of the interfaces.

like image 26
Matt Smith Avatar answered Jan 31 '23 00:01

Matt Smith