Beckam White
Beckam White

Reputation: 143

How to pass inherited types in generic methods

I have a generic method which takes in an Event inherited type (e.g. MouseMoveEvent) and a function to execute based on if the local event matches the type of the event passed as TEvent

public bool Dispatch<TEvent>(TEvent e, Func<TEvent, bool> func) where TEvent : Event
        {
            if (_event.GetEventType() == e.GetEventType())
            {
                Event.Handled = func(e);
                return true;
            }

            return false;
        }
public void OnEvent(Event e)
{
    EventDispatcher dispatcher = new EventDispatcher(e);
    dispatcher.Dispatch<MouseMoveEvent>(e, OnCloseWindow);
}

When I try to call the method, VS gives me the error "Cannot convert from MouseMoveEvent to Event". This makes sense to me, as the TEvent type needs to be the same. I guess I'm asking if there is any way I can pass the Event in seeing as MouseMoveEvent inherits Event.

Thanks!

Upvotes: 1

Views: 49

Answers (2)

Beckam White
Beckam White

Reputation: 143

Fixed this by changing the method from

public bool Dispatch<TEvent>(TEvent e, Func<TEvent, bool> func) where TEvent : Event
        {
            if (_event.GetEventType() == e.GetEventType())
            {
                Event.Handled = func(e);
                return true;
            }

            return false;
        }

to

public bool Dispatch<TEvent>(Event e, Func<TEvent, bool> func) where TEvent : Event
        {
            if (e is TEvent && Event.GetEventType() == e.GetEventType())
            {
                Event.Handled = func(e as TEvent);
                return true;
            }

            return false;
        }

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1062540

options:

If it doesn't matter that T is specifically MouseMoveEvent:

  • dispatcher.Dispatch<Event>(e, OnCloseWindow);
  • dispatcher.Dispatch(e, OnCloseWindow); (implicit)

If it matters, and e actually is a MouseMoveEvent:

  • dispatcher.Dispatch<MouseMoveEvent>((MouseMoveEvent)e, OnCloseWindow); (cast)
  • dispatcher.Dispatch((MouseMoveEvent)e, OnCloseWindow); (implicit and cast)

If it matters, and you don't know, perhaps test:

if (e is MouseMoveEvent mme)
{
   // more specific, with mme
}
else
{
  // less specific, with e
}

Upvotes: 2

Related Questions