C#订阅基于参数类型的事件? [英] C# subscribe to events based on parameter type?

查看:135
本文介绍了C#订阅基于参数类型的事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个指挥官类,它处理的命令。所有这些命令贯彻落实的ICommand 接口。基本上命令模式...

I have a Commander class, which handles commands. All these commands implement the ICommand interface. Basically the command pattern...

现在我想创造类似的东西到事件为每个特定类型的命令,实际上并没有使事件在指挥官每个特定类型。该指挥官不应该被耦合到每个类型的命令

Now I want to create something similar to an event for each specific type of command, without actually making an event for each specific type in the commander. The commander should not be coupled to each type of command.

所以我的命令有一个方法无效订阅< T>(动作< T>回调)其中T:ICommand的。如果一个用户呼叫该用的方法无效MyAttackCommandHandler(AttackCommand ATT)作为参数,我希望用户得到一个回调只为 AttackCommands 。然而另一个类也可以订阅不同的命令。

So my command has a method void Subscribe<T>(Action<T> callback) where T: ICommand. If a subscriber calls this with the method void MyAttackCommandHandler(AttackCommand att) as the parameter, I expect the subscriber to get a callback only for AttackCommands. However another class can also subscribe for a different command.

我试图创建一个字典,该参数(那种命令的)类型映射到用户列表:词典<类型,列表与LT;动作<&的ICommand GT;>> _subscriptions ,然后我的订阅方法看起来是这样的:

I tried creating a dictionary, that maps the type of the parameter (the kind of command) to a list of subscribers: Dictionary<Type, List<Action<ICommand>>> _subscriptions, and then my subscribe method would look something like:

public void Subscribe<T>(Action<T> callback)
    where T: ICommand
{
    Type type = typeof(T);
    if (_subscriptions.ContainsKey(type))
    {
        List<Action<ICommand>> subscribtions = _subscriptions[type];
        subscribtions.Add(callback);
    }
    else ... //create a new entry in _subscriptions
}

然而,这并不工作,因为回调不是类型动作<的; ICommand的> ,但动作< AttackCommand> 例如

This however doesn't work because callback isn't of the type Action<ICommand>, but of Action<AttackCommand> for instance.

如何将一个实现这个干净

How would one implement this cleanly?

谢谢!

推荐答案

试试这个

subscribtions.Add(i => callback((T)i));

如果以上不工作,请提供完整的示例,说明你的问题。
事情是这样的:

If the above doesn't work please provide a full example that shows your problem. Something like this:

using System;
using System.Collections.Generic;

namespace Example
{
    class Program
    {
        static void Main(string[] args)
        {
            Commander C = new Commander();
            C.Subscribe((MyCommand i) => { Console.WriteLine(i.Value); });
            C.Subscribe((SquareMyCommand i) => { Console.WriteLine(i.Value); });
            C.Subscribe((SquareMyCommand i) => { Console.WriteLine("**" + i.Value + "**"); });

            C.Do(new MyCommand(2));//1 callback , Prints 2
            C.Do(new SquareMyCommand(3));//2 callbacks, Prints 9 , **9**
            Console.ReadLine();
        }
    }

    public class Commander
    {
        Dictionary<Type, List<Action<ICommand>>> dictionary = new Dictionary<Type, List<Action<ICommand>>>();
        public void Subscribe<T>(Action<T> callback) where T : ICommand
        {
            Type type = typeof(T);

            List<Action<ICommand>> subscribtions = null;
            dictionary.TryGetValue(type, out subscribtions);
            if (subscribtions == null)
            {
                subscribtions = new List<Action<ICommand>>();
                dictionary.Add(type, subscribtions);
            }
            subscribtions.Add(i => callback((T)i));
        }

        public void Do<T>(T t) where T : ICommand
        {
            foreach (var item in dictionary[t.GetType()])
                item(t);
        }
    }

    public class MyCommand : ICommand
    {
        public MyCommand(int x) { Value = x; }
        public int Value { get; set; }
    }
    public class SquareMyCommand : ICommand
    {
        public SquareMyCommand(int x) { Value = x * x; }
        public int Value { get; set; }
    }
    public interface ICommand
    {
        int Value { get; set; }
    }
}

这篇关于C#订阅基于参数类型的事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆