Search code examples
c#genericscasting

Cast to generic type in C#


I have a Dictionary to map a certain type to a certain generic object for that type. For example:

typeof(LoginMessage) maps to MessageProcessor<LoginMessage>

Now the problem is to retrieve this generic object at runtime from the Dictionary. Or to be more specific: To cast the retrieved object to the specific generic type.

I need it to work something like this:

Type key = message.GetType();
MessageProcessor<key> processor = messageProcessors[key] as MessageProcessor<key>;

Hope there is a easy solution to this.

Edit: I do not want to use Ifs and switches. Due to performance issues I cannot use reflection of some sort either.


Solution

  • Does this work for you?

    interface IMessage
    {
        void Process(object source);
    }
    
    class LoginMessage : IMessage
    {
        public void Process(object source)
        {
        }
    }
    
    abstract class MessageProcessor
    {
        public abstract void ProcessMessage(object source, object type);
    }
    
    class MessageProcessor<T> : MessageProcessor where T: IMessage
    {
        public override void ProcessMessage(object source, object o) 
        {
            if (!(o is T)) {
                throw new NotImplementedException();
            }
            ProcessMessage(source, (T)o);
        }
    
        public void ProcessMessage(object source, T type)
        {
            type.Process(source);
        }
    }
    
    
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<Type, MessageProcessor> messageProcessors = new Dictionary<Type, MessageProcessor>();
            messageProcessors.Add(typeof(string), new MessageProcessor<LoginMessage>());
            LoginMessage message = new LoginMessage();
            Type key = message.GetType();
            MessageProcessor processor = messageProcessors[key];
            object source = null;
            processor.ProcessMessage(source, message);
        }
    }
    

    This gives you the correct object. The only thing I am not sure about is whether it is enough in your case to have it as an abstract MessageProcessor.

    Edit: I added an IMessage interface. The actual processing code should now become part of the different message classes that should all implement this interface.