Cast to generic type in C#

前端 未结 13 903
野性不改
野性不改 2021-01-30 20:27

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

typeof(LoginMessage) maps to MessageProcessor

        
13条回答
  •  被撕碎了的回忆
    2021-01-30 21:12

    Please see if following solution works for you. The trick is to define a base processor interface which takes a base type of message.

    interface IMessage
    {
    }
    
    class LoginMessage : IMessage
    {
    }
    
    class LogoutMessage : IMessage
    {
    }
    
    class UnknownMessage : IMessage
    {
    }
    
    interface IMessageProcessor
    {
        void PrcessMessageBase(IMessage msg);
    }
    
    abstract class MessageProcessor : IMessageProcessor where T : IMessage
    {
        public void PrcessMessageBase(IMessage msg)
        {
            ProcessMessage((T)msg);
        }
    
        public abstract void ProcessMessage(T msg);
    
    }
    
    class LoginMessageProcessor : MessageProcessor
    {
        public override void ProcessMessage(LoginMessage msg)
        {
            System.Console.WriteLine("Handled by LoginMsgProcessor");
        }
    }
    
    class LogoutMessageProcessor : MessageProcessor
    {
        public override void ProcessMessage(LogoutMessage msg)
        {
            System.Console.WriteLine("Handled by LogoutMsgProcessor");
        }
    }
    
    class MessageProcessorTest
    {
        /// 
        /// IMessage Type and the IMessageProcessor which would process that type.
        /// It can be further optimized by keeping IMessage type hashcode
        /// 
        private Dictionary msgProcessors = 
                                    new Dictionary();
        bool processorsLoaded = false;
    
        public void EnsureProcessorsLoaded()
        {
            if(!processorsLoaded)
            {
                var processors =
                    from processorType in Assembly.GetExecutingAssembly().GetTypes()
                    where processorType.IsClass && !processorType.IsAbstract &&
                          processorType.GetInterface(typeof(IMessageProcessor).Name) != null
                    select Activator.CreateInstance(processorType);
    
                foreach (IMessageProcessor msgProcessor in processors)
                {
                    MethodInfo processMethod = msgProcessor.GetType().GetMethod("ProcessMessage");
                    msgProcessors.Add(processMethod.GetParameters()[0].ParameterType, msgProcessor);
                }
    
                processorsLoaded = true;
            }
        }
    
        public void ProcessMessages()
        {
            List msgList = new List();
            msgList.Add(new LoginMessage());
            msgList.Add(new LogoutMessage());
            msgList.Add(new UnknownMessage());
    
            foreach (IMessage msg in msgList)
            {
                ProcessMessage(msg);
            }
        }
    
        public void ProcessMessage(IMessage msg)
        {
            EnsureProcessorsLoaded();
            IMessageProcessor msgProcessor = null;
            if(msgProcessors.TryGetValue(msg.GetType(), out msgProcessor))
            {
                msgProcessor.PrcessMessageBase(msg);
            }
            else
            {
                System.Console.WriteLine("Processor not found");
            }
        }
    
        public static void Test()
        {
            new MessageProcessorTest().ProcessMessages();
        }
    }
    

提交回复
热议问题