2010-05-06 20 views
1

我有一個流,表示消息的序列化對象被週期性地轉儲。對象是非常有限數量的類型之一,除了實際的字節序列以外,我無法知道它是什麼類型的消息。這是一個通用反序列化對象的好方法嗎?

我想嘗試將其反序列化爲特定類型的對象,並且如果引發異常,請再次嘗試使用下一個類型。

我有一個看起來像這樣的接口:

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>,即使AppleMessageIMessage。有沒有不同的方式來做到這一點?

此外,有沒有更好的方式反序列化未知(但限制)類型的數據?

回答

1

用指示類型的字段擴展您的消息,以便您可以選擇正確的解串器。

(可選)使用現有的協議,如protobuf,因此您不必重新發明輪子。

+0

+1不重新發明。當然,這個問題已經被解決了。 – spender 2010-05-06 23:14:40

相關問題