开发者

Compiler error on passing member function to a delegate

I am getting a compiler error when I try to pass a member function (from SoundManager class) to a delegate (in EventManager).

Error: Argument 2: cannot convert from 'method group' to 'Event_Sharp.FunctionHandler'

Code:

public delegate void FunctionHandler(IEvent evnt);

EventManager开发者_StackOverflow社区::

public void RegisterListener(int type, FunctionHandler handler)
{
    // ...
}

SoundManager.cs (constructor):

EventManager.Instance.RegisterListener(Event_Bullet_Fired.GetType(), HandleBulletFired );

where HandleBulletFired is a member of SoundManager:

void HandleBulletFired(Event_Bullet_Fired evnt)
{
    // ...
}

and, Event_Bullet_Fired implements IEvent interface. Can someone please tell me why I am getting this error and why I cannot use HandleBulletFired as a delegate ?


What you're doing is not typesafe, and hence the compiler is complaining.

Think about it like this:

interface IAnimal { }
class Lion : IAnimal { public void Roar() {} }
class Giraffe: IAnimal { }
delegate void D(IAnimal animal);
static void M(Lion lion) { lion.Roar(); }

Now you say

D d = M;

Do you see why that doesn't work? Because nothing is stopping you from saying

d(new Giraffe());

and now you just made a giraffe roar. Or, rather, you just crashed the CLR.

To prevent you from doing this, the compiler stops the attempt to make the unsafe assignment.

Note that you can go the other way:

delegate void D2(Lion lion);
static void M2(IAnimal animal) {}
...
D2 d2 = M2;

because now you're going to pass a Lion to d2, which will pass an IAnimal to M2, and Lion is guaranteed to implement IAnimal.

The highfalutin way of saying this is that method group to delegate conversions are contravariant in their parameter types and covariant in their return types.

See my series of blog articles on covariance and contravariance for more information.


Maybe you should try to cast HandleBulletFired to FunctionHandler:

EventManager.Instance.RegisterListener(Event_Bullet_Fired.GetType(), (FunctionHandler)HandleBulletFired );


It doesn't look like this Event_Bullet_Fired.GetType() returns int as RegisterListener method requires:

public void RegisterListener(int type, FunctionHandler handler)

Updated:

I think that the reason of error is that Event_Bullet_Fired is more specific that IEvent. Try substitute Event_Bullet_Fired to IEvent in the HandleBulletFired method declaration:

void HandleBulletFired(IEvent evt)
{
    Event_Bullet_Fired bullerFiredEvent = (Event_Bullet_Fired)evt;
    // ...
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜