C#根据参数类型订阅事件?
我有一个C#根据参数类型订阅事件?,c#,C#,我有一个Commander类,它处理命令。所有这些命令都实现了ICommand接口。基本上是命令模式 现在,我想为每个特定类型的命令创建类似于事件的内容,而不实际为指挥官中的每个特定类型创建事件。指挥官不应与每种类型的命令相耦合 因此,我的命令有一个方法voidsubscribe(actioncallback),其中T:ICommand。如果订阅者使用方法void MyAttackCommandHandler(AttackCommand att)作为参数调用此函数,我希望订阅者仅为AttackC
Commander
类,它处理命令。所有这些命令都实现了ICommand
接口。基本上是命令模式
现在,我想为每个特定类型的命令创建类似于事件的内容,而不实际为指挥官中的每个特定类型创建事件。指挥官不应与每种类型的命令相耦合
因此,我的命令有一个方法voidsubscribe(actioncallback),其中T:ICommand
。如果订阅者使用方法void MyAttackCommandHandler(AttackCommand att)
作为参数调用此函数,我希望订阅者仅为AttackCommands
获得回调。但是,另一个类也可以订阅不同的命令
我尝试创建一个字典,它将参数的类型(命令的类型)映射到订阅者列表:dictionary\u subscriptions
,然后我的subscribe方法如下所示:
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
}
public void Subscribe(操作回调)
其中T:ICommand
{
类型=类型(T);
if(_subscriptions.ContainsKey(类型))
{
列表订阅=_订阅[类型];
subscribtions.Add(回调);
}
else…//在\订阅中创建一个新条目
}
但是,这不起作用,因为回调
不是操作
类型,而是操作
类型
如何干净地实现这一点
谢谢 试试这个
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<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; }
}
}
使用系统;
使用System.Collections.Generic;
名称空间示例
{
班级计划
{
静态void Main(字符串[]参数)
{
指挥官C=新指挥官();
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(新的MyCommand(2));//1回调,打印2
C.Do(新的SquareMyCommand(3));//2次回调,打印9,**9**
Console.ReadLine();
}
}
公营班长
{
字典=新字典();
public void Subscribe(操作回调),其中T:ICommand
{
类型=类型(T);
列表subscribtions=null;
TryGetValue(类型,外下标);
if(subscribtions==null)
{
subscribtions=新列表();
添加(类型、订阅);
}
Add(i=>callback((T)i));
}
公共无效Do(T T),其中T:ICommand
{
foreach(字典[t.GetType()]中的变量项)
项目(t);
}
}
公共类MyCommand:ICommand
{
公共MyCommand(int x){Value=x;}
公共int值{get;set;}
}
公共类SquareMyCommand:ICommand
{
公共SquareMyCommand(int x){Value=x*x;}
公共int值{get;set;}
}
公共接口ICommand
{
int值{get;set;}
}
}
你的AttackCommand
实现了ICommand
对吗?如果你有一个像BaseCommand
这样的基类,它实现了ICommand
,并且有AttackCommand
扩展BaseCommand
应该可以工作?@Rahul这是正确的。那么它应该工作得很好,因为attackcomand是我命令。@Rahul不,没有。你把它倒过来了。问题是ICommand不是AttackCommand。(尽管AttackCommand是一个ICommand:P),因此您不能将操作添加到操作列表中。列表要求其中的所有操作都接受所有类型的命令,我尝试添加一个只接受攻击命令的操作。您可能希望添加一些解释,说明为什么在问题示例中这样做有效。