C#根据参数类型订阅事件?
我有一个Commander
类,它处理命令。 所有这些命令都实现了ICommand
接口。 基本上是命令模式……
现在我想为每种特定类型的命令创建类似于event
的内容,而不是实际为命令器中的每个特定类型创建event
。 指挥官不应该与每种命令相联系。
所以我的命令有一个方法void Subscribe(Action callback) where T: ICommand
。 如果订户使用void MyAttackCommandHandler(AttackCommand att)
作为参数调用它,我希望订阅者只能获得AttackCommands
的回调。 但是,另一个类也可以订阅不同的命令。
我尝试创建一个字典,将参数的类型(命令的类型)映射到订阅者列表: Dictionary<Type, List<Action>> _subscriptions
,然后我的subscribe方法看起来像:
public void Subscribe(Action callback) where T: ICommand { Type type = typeof(T); if (_subscriptions.ContainsKey(type)) { List<Action> subscribtions = _subscriptions[type]; subscribtions.Add(callback); } else ... //create a new entry in _subscriptions }
但这不起作用,因为callback
不是Action
类型,而是Action
。
如何干净利落地实现这一目标?
谢谢!
试试这个
subscribtions.Add(i => callback((T)i));
如果上述方法无效,请提供一个显示问题的完整示例。 像这样的东西:
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>> dictionary = new Dictionary>>(); public void Subscribe(Action callback) where T : ICommand { Type type = typeof(T); List> subscribtions = null; dictionary.TryGetValue(type, out subscribtions); if (subscribtions == null) { subscribtions = new List>(); dictionary.Add(type, subscribtions); } subscribtions.Add(i => callback((T)i)); } public void Do(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; } } }