Q:

Callback Disappears If I Use PointerEventData Instead of BaseEventData

I have a callback I am trying to implement with UnityEvents.
On my object I have an event system and I have an OnDragEvent. 

Here is the callback code:
public void UpdatePosition(BaseEventData data)
{
    Debug.Log("UPDATE" + data.GetType());
}

Now if I run this and drag the object, it works and its printing the data type as PointerEventData
However if I change my UpdatePosition to:
public void UpdatePosition(PointerEventData data)
{
    Debug.Log("UPDATE" + data.GetType());
}

I lose connection to the callback it cannot find it. It does not appear in the drop downlist anymore.
I used to use an IDropHandler and that would work, but I am trying to use the GUI now and I am very confused as to why I can't call the callback I want with a PointerEventData argument?

A:

I'm guessing the problem is that the delegate is declared something like:
public delegate void CallbackHandlerDelegate(BaseEventData data);

This means that any methods that implement the callback handler must have the same method signature, including the type, even if PointerEventData derives from BaseEventData.
The problem is that when using a "generic" delegate like the one above you can't substitute more derived types for the BaseEventData argument without changing the method signature.
The fix is simple though, instead of trying to force the type in the argument list, just cast it in the method:
public void UpdatePosition(BaseEventData data)
{
    var pEventData = data as PointerEventData;

    if (pEventData == null)
        return;

    //Do whatever with pEventData here
    Debug.Log("UPDATE" + data.GetType());
}

Notice the use of as here instead of doing something like this:
var pEventData = (PointerEventData)data;

Which is also legal, except using as lets the cast fail (in case something other than PointerEventData is passed in without throwing an exception. The null check helps that out because as will return the object as null if the cast fails.

