I am trying to implement my own messaging system for a Unity game. I have a basic version - a very simplified example:
All of this works great. What I would like to do now is to implement some βmagicβ that allow calling a message handler with an actual derived type, for example:
private bool MessageHandler(MyMessage message) {
This would mean that the message processing code in thousands of scripts should not bother to pass the Message object to the correct derived type - it will already be of this type. That would be much more convenient. I feel that I could somehow make use of generics, delegates, expression trees, covariance and / or contravariance, but I just don't get it!
I tried a lot of different things and feel like getting close, but I just can't get there. These are two partial solutions that I could come up with:
// Messaging class: private Dictionary<Type, List<Delegate>> listeners; // Delegate instead of Func<Message, bool>. public void AddListener<T>(Func<T, bool> listener) where T : Message { // Func<T, bool> instead of Func<Message, bool>. this.listeners[typeof(T)].Add(listener); } public void SendMessage<T>(T message) where T : Message { foreach (Delegate listener in this.listeners[typeof(T)]) { listener.Method.Invoke(method.Target, new object[] { message }); // Partial solution 1. ((Func<T, bool>)listener)(message); // Partial solution 2. } }
Partial Solution 1 works fine, but it uses reflection, which is not really an option, given the performance - it's a game, and the messaging system will be used a lot. Partial Solution 2 works, but only as long as the general parameter T is available. The messaging system will also have a queue of Message objects that it will process, and T will not be available there.
Is there any way to achieve this? I would really appreciate any help anyone could offer!
Finally, I want to note that I use Unity, which uses Mono-.NET 4, is not an option, and as far as I know, this eliminates the use of "dynamic".