开发者

Delegate inheritance explanation

I understand that an action is just a pre-declared delegate that can accept a single parameter of the type defined. so Action<String> represents a me开发者_开发知识库thod that has no return and accepts a single string parameter. So far so good.

In my code i have this method:

public void Send<TMessageType>(Types.MessageBase<TMessageType> message)
        {
            Console.WriteLine("Message Sent");
            List<Delegate> subscriptions;
            if (register.TryGetValue(typeof(TMessageType), out subscriptions))
            {
                foreach (Delegate subscription in subscriptions)
                {
                    Console.WriteLine("Invoking....");
                    subscription.DynamicInvoke(message);
                }
            }
        }

All of the Delegates in the subscriptions variable were actually instantiated as actions. My question is, why does my code work? Why dont i need to cast my delegate back into an action (it would be Action<TMessageType>), before i can use it? surely the default delegate type has no idea what parameters to expect?


Well the short answer is because your call to DynamicInvoke is a late-bound call and doesn't actually know whether or not it even needs parameters.

MSDN

Dynamically invokes (late-bound) the method represented by the current delegate.

As a side note:
Given that you have knowledge of the type being passed to the Action you should probably refactor your code to directly invoke the actions and not use DynamicInvoke if you can avoid it as there will be a performance impact. If you cannot avoid it due to restrictions not shown then so be it.

        List<Action<Types.MessageBase<TMessageType>>> subscriptions;
        if (register.TryGetValue(typeof(TMessageType), out subscriptions))
        {
            foreach (var subscription in subscriptions)
            {
                Console.WriteLine("Invoking....");
                subscription(message);
            }
        }

Of course I don't know what would be involved in refactoring the TryGetValue call.


no it does not know and doesn't care - it takes a bunch of "object"-parameters and calls your action with it. It is not checked at compiletime but at runtime - see here for details


You're using DynamicInvoke, which, as its name implies, invokes dynamically the delegate. It's an order of magnitude slower then Invoke but is able to match automatically the parameter type, at runtime rather than relying on compile time information.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜