首先我會從數據流中讀取器(這樣我就可以不用寫處理流測試)分隔包分析器。然後考慮一個基類,它提供了讀取數據包和寫入數據包的方法。
此外,我將建立一個字典(一個時間才把它重新用於未來的呼叫),如下所示:
編輯:這到底是怎麼回事的幾點說明:
第一:
[Accepts(5)]
這條線是C#的屬性(由AcceptsAttribute
定義)表示,所述FooMessage
類接受的5.
第二消息ID:
是字典被在運行時通過反射建造。你只需要做一次這樣的事情(我會把它放到一個單例類中,你可以把一個測試用例放到它上面來運行,以確保字典的正確構建)。
三:
var m = messages[5]();
此行得到以下編譯lambda表達式了字典,並執行它:
()=>(Message)new FooMessage();
(演員陣容是必要的,.NET 3.5,但不是由於4.0對於如何工作的協變變化,在4.0中,類型Func<FooMessage>
的對象可以被分配給類型爲Func<Message>
的對象。)
這lambda表達式被賦值線字典制作過程中內置:
Value = (Func<Message>)Expression.Lambda(Expression.Convert(Expression.New(t), typeof(Message))).Compile()
(這裏的轉換是必要的投編譯lambda表達式Func<Message>
)
我做了這種方式,因爲我碰巧在那個時候已經有了我可以使用的類型。你也可以使用:
Value =()=>(Message)Activator.CreateInstance(t)
但我相信,這將是比較慢(這裏的轉換是需要改變Func<object>
爲Func<Message>
)。
四:
.SelectMany(o => o.Keys.Select(key => new { Key = key, o.Value }))
這樣做是因爲我覺得你可能在將不止一次AcceptsAttribute
更上一個類值(接受每班超過一個消息ID)。這也具有忽略不具有消息id屬性的消息類的好的副作用(否則Where方法需要具有確定該屬性是否存在的複雜性)。
嗨比爾,謝謝你的回答。我試圖讓我的頭靠近它! 什麼... [接受(5)] ...表示法? 字典是否在運行時被反射填充? – Prembo 2010-07-20 04:58:40
感謝您的詳細解釋。我學到了很多! 這是一個非常優雅和可擴展的解決方案。優秀。 我 – Prembo 2010-07-27 06:55:25