我有一个流,定期转储表示消息的序列化对象。对象是非常有限数量的类型之一,除了到达的实际字节序列之外,我无法知道它是什么类型的消息。
我想简单地尝试将其反序列化为特定类型的对象,如果抛出异常,请尝试使用下一种类型。
我有一个如下所示的界面:
public interface IMessageHandler<T> where T : class, IMessage {
T Handle(string message);
}
// elsewhere:
// (These are all xsd.exe-generated classes from an XML schema.)
public class AppleMessage : IMessage { ... }
public class BananaMessage : IMessage { ... }
public class CoconutMessage : IMessage { ... }
然后我写了一个GenericHandler<T>
看起来像这样:
public class GenericHandler<T> : IMessageHandler<T> where T: class, IMessage {
public class MessageHandler : IMessageHandler {
T IMessageHandler.Handle(string message) {
T result = default(T);
try {
// This utility method tries to deserialize the object with an
// XmlSerializer as if it were an object of type T.
result = Utils.SerializationHelper.Deserialize<T>(message);
} catch (InvalidCastException e) {
result = default(T);
}
return result;
}
}
}
使用我的GenericHandler<T>
(或类似的东西),我现在想要使用处理程序填充一个集合,每个处理程序处理不同的IMessage
(Apple*
,{{1我的例子中有}和Banana*
个类)。然后我想调用特定消息上的每个处理程序的Coconut*
方法,看它是否可以反序列化。如果我得到一个null结果,移动到下一个处理程序;否则,该消息已被反序列化。
看起来像这样:
我做了这样的事情:
Handle
我很确定这会因为协方差限制而无效,因为public object Process(string message) {
var handlers = new ArrayList {
new MessageHandler<AppleMessage>(),
new MessageHandler<BananaMessage>(),
new MessageHandler<CoconutMessage>(),
}
foreach (IMessageHandler<IMessage> h in handlers) {
var result = h.Handle(message);
// Message successfully handled! Return the result.
if (result != null) { return result; }
}
// Couldn't handle the message; return null.
return null;
}
不是IMessageHandler<AppleMessage>
,即使IMessageHandler<IMessage>
是AppleMessage
}。有没有不同的方法来做到这一点?
此外,是否有更好的方法来反序列化未知(但受限制)类型的数据?