我有一個流,表示消息的序列化對象被週期性地轉儲。對象是非常有限數量的類型之一,除了實際的字節序列以外,我無法知道它是什麼類型的消息。這是一個通用反序列化對象的好方法嗎?
我想嘗試將其反序列化爲特定類型的對象,並且如果引發異常,請再次嘗試使用下一個類型。
我有一個看起來像這樣的接口:
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>
(類似於它或某事),我d現在想用處理程序填充集合,每個處理程序都處理不同的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
。有沒有不同的方式來做到這一點?
此外,有沒有更好的方式反序列化未知(但限制)類型的數據?
+1不重新發明。當然,這個問題已經被解決了。 – spender 2010-05-06 23:14:40