C# 行动字典<;T>;代表
我将对象XML序列化消息放入名为MessageRouter的类中。XML包含从中序列化的类型名称,我需要能够调用不同的委托方法,这取决于运行时之前未知的类型。我不是特别擅长泛型,所以希望这对某些人来说是有意义的 我希望MessageRouter提供一个RegisterDelegateForType方法,如下所示:C# 行动字典<;T>;代表,c#,.net,generics,C#,.net,Generics,我将对象XML序列化消息放入名为MessageRouter的类中。XML包含从中序列化的类型名称,我需要能够调用不同的委托方法,这取决于运行时之前未知的类型。我不是特别擅长泛型,所以希望这对某些人来说是有意义的 我希望MessageRouter提供一个RegisterDelegateForType方法,如下所示: myMessageRouter.RegisterDelegateForType(new Action<MySerializableType>(myActionHandler
myMessageRouter.RegisterDelegateForType(new Action<MySerializableType>(myActionHandler));
因此,我的问题是:
类型
作为键,一个泛型操作
作为值,并让RegisterDeleteGateForType方法填充字典您不能按描述的那样执行此操作,原因很明显-即使允许,示例中的最后一行代码(检索委托然后调用它的代码)将是非类型安全的,因为您正在调用
操作
-该操作期望T
作为参数-但将其传递给反序列化对象
,类型为对象
。如果没有强制转换,它无法在普通代码中工作,为什么您希望能够绕过您的案例的类型检查
在最简单的情况下,您可以执行以下操作:
Dictionary<Type, Delegate> registeredDelegates;
...
registeredDelegates[xmlSerializedType].DynamicInvoke(deserializedObject);
然后注册如下类型:
Dictionary<Type, Action<T>> registeredDelegates;
myMessageRouter.RegisterDelegateForType<MySerializableType>(
o => myActionHandler((MySerializableType)o)
);
现在,呼叫者只需执行以下操作:
RegisterDelegateForType<MySerializableType>(myHandler)
RegisterDelegateForType(myHandler)
所以对你的客户来说是完全安全的。当然,您仍有责任正确地执行此操作(即,将正确类型的对象传递给从字典中检索到的委托)。我不确定这是否完全回答了您的问题,但我编写的一个类将实现您想要的功能。我无法判断您是否希望动作委托接受类型化对象,但在伪代码中,您向其传递了一个“对象”进行反序列化,因此我编写了相应的类,因此它不使用泛型:
public delegate void Action(object o);
public class DelegateDictionary {
private IDictionary _dictionary = new Hashtable();
public void Register<T>(Action action) {
_dictionary[typeof(T)] = action;
}
public Action Get<T>() {
return (Action)_dictionary[typeof(T)];
}
public static void MyFunc(object o) {
Console.WriteLine(o.ToString());
}
public static void Run() {
var dictionary = new DelegateDictionary();
dictionary.Register<string>(MyFunc);
// Can be converted to an indexer so that you can use []'s
var stringDelegate = dictionary.Get<string>();
stringDelegate("Hello World");
}
}
公共委托无效操作(对象o);
公共类委派字典{
私有IDictionary_dictionary=新哈希表();
公共无效登记册(行动){
_字典[类型(T)]=动作;
}
公共行动{
返回(动作)_字典[typeof(T)];
}
公共静态void MyFunc(对象o){
Console.WriteLine(o.ToString());
}
公共静态无效运行(){
var dictionary=新的DelegateDictionary();
字典寄存器(MyFunc);
//可以转换为索引器,以便您可以使用[]
var stringDelegate=dictionary.Get();
stringDelegate(“你好,世界”);
}
}
我相信这将实现您想要的功能。为什么不将IDictionary作为字典呢?我想我正在等待routeNpingme是否需要支持void Action(T)的委托类型;如果是这样的话,您就不能使用字典,而这个设计可以很容易地修改以支持它。如果没有,那么是的,最好是一本字典。即使他需要支持行动,如果我使用字典,设计会更好。
private Dictionary<Type, Action<object>> registeredDelegates;
void RegisterDelegateForType<T>(Action<T> d)
{
registeredDelegates.Add(typeof(T), o => d((T)o));
}
RegisterDelegateForType<MySerializableType>(myHandler)
public delegate void Action(object o);
public class DelegateDictionary {
private IDictionary _dictionary = new Hashtable();
public void Register<T>(Action action) {
_dictionary[typeof(T)] = action;
}
public Action Get<T>() {
return (Action)_dictionary[typeof(T)];
}
public static void MyFunc(object o) {
Console.WriteLine(o.ToString());
}
public static void Run() {
var dictionary = new DelegateDictionary();
dictionary.Register<string>(MyFunc);
// Can be converted to an indexer so that you can use []'s
var stringDelegate = dictionary.Get<string>();
stringDelegate("Hello World");
}
}