我有对象XML序列化消息进入一个名为MessageRouter的类.XML包含它从中序列化的类型名称,我需要能够根据直到运行时才知道的类型调用不同的委托方法.我在仿制药方面并不是非常强大,所以希望这对某人有意义......
我希望MessageRouter提供一个RegisterDelegateForType方法,如下所示:
myMessageRouter.RegisterDelegateForType(new Action<MySerializableType>(myActionHandler));
Run Code Online (Sandbox Code Playgroud)
然后将类型或类型的字符串表示形式存储在字典中,如下所示:
Dictionary<Type, Action<T>> registeredDelegates;
Run Code Online (Sandbox Code Playgroud)
这样,我可以执行类似下面的伪代码,调用类型的已分配委托并传递反序列化的对象:
Type xmlSerializedType = TypeFromXmlString(incomingXml);
object deserializedObject = DeserializeObjectFromXml(xmlSerializedType, incomingXml);
// then invoke the action and pass in the deserialized object
registeredDelegates[xmlSerializedType](deserializedObject);
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
Type
键作为键和泛型Action<T>
作为值的Dictionary ,并使用RegisterDelegateForType方法填充字典?Pav*_*aev 23
你不能这样做,原因很明显 - 即使以某种方式允许,你的例子中的最后一行代码(检索委托然后调用它的那一行)将是非类型安全的,因为你正在调用Action<T>
-期望T
作为一个论点 - 然而传递它deserializedObject
,这是类型object
.如果没有演员表单,它将无法在普通代码中工作,为什么您希望能够绕过案例的类型检查?
在最简单的情况下,您可以执行以下操作:
Dictionary<Type, Delegate> registeredDelegates;
...
registeredDelegates[xmlSerializedType].DynamicInvoke(deserializedObject);
Run Code Online (Sandbox Code Playgroud)
当然,这将允许某人添加一个委托,该委托对字典采用多于或少于一个参数,并且您只能DynamicInvoke
在运行时找到通话.但是,实际上没有任何方法可以定义一个"任何委托,但只有1个参数"的类型.一个更好的选择可能是:
Dictionary<Type, Action<object>> registeredDelegates
Run Code Online (Sandbox Code Playgroud)
然后注册这样的类型:
myMessageRouter.RegisterDelegateForType<MySerializableType>(
o => myActionHandler((MySerializableType)o)
);
Run Code Online (Sandbox Code Playgroud)
上面的代码片段使用的是C#3.0 lambdas,但你可以使用C#2.0匿名委托来做同样的事情 - 如果稍微冗长一点.现在你不需要使用DynamicInvoke
- lambda本身将进行适当的转换.
最后,您可以RegisterDelegateForType
通过使lambda创建为通用来将lambda创建封装在自身中.例如:
private Dictionary<Type, Action<object>> registeredDelegates;
void RegisterDelegateForType<T>(Action<T> d)
{
registeredDelegates.Add(typeof(T), o => d((T)o));
}
Run Code Online (Sandbox Code Playgroud)
而现在呼叫者可以这样做:
RegisterDelegateForType<MySerializableType>(myHandler)
Run Code Online (Sandbox Code Playgroud)
所以它对您的客户来说是完全类型安全的.当然,您仍然有责任正确地做到这一点(即将正确类型的对象传递给您从字典中检索的委托).
归档时间: |
|
查看次数: |
8501 次 |
最近记录: |