【发布时间】:2010-05-06 22:55:49
【问题描述】:
我有一个流,表示消息的序列化对象会定期转储到该流上。对象是数量非常有限的类型之一,除了实际到达的字节序列外,我无法知道它是什么类型的消息。
我想简单地尝试将其反序列化为特定类型的对象,如果抛出异常,请使用下一个类型重试。
我的界面如下所示:
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*、Banana* 和Coconut* 类在我的例子中)。然后我想在特定消息上调用每个处理程序的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 是 IMessage。有没有其他方法可以做到这一点?
此外,有没有更好的方法来反序列化未知(但受限)类型的数据?
【问题讨论】:
标签: c# generics serialization